Node.js初体验

Node.js简介

node.js的运行环境

1.V8引擎对js代码进行解析与执行

2.内置API:fs、path、http...等,提供了一些能力,能够使得js调用这些API去做一些后端的事情

流程:我们在node.js的运行环境中编写待执行的JavaScript代码,代码中可以调用其内置的API,然后交给V8引擎进行解析和执行

特别注意:在Node.js的运行环境中是无法调用DOM、BOM等浏览器内置的API的,因为Node.js是一个独立的运行环境,在Node中只提供了node相关的api,而没有浏览器相关的API。因此....

Node.js可以做什么

Node.js好学吗?

好学!插入表情包

只要会JavaScript,就能学会Node

Node.js怎么学

其实是跟学习JavaScript的路劲是非常相似的

浏览器中的JavaScript学习路径:

JavaScript基础语法+浏览器内置API(DOM+BOM)+第三方库

Node.js的学习自路径:

JavaScript基础语法+Node.js内置API模块(fs、path、http等),第三方模块

Node.js环境安装

如果希望通过Node.js来运行JavaScript代码,则需要在计算机上安装Node环境才行

LTS版本:

1.LTS为长期稳定版本,对于追求稳定性和企业级项目来说,推荐安装LTS版本的Node.js

Current版本:

1.新特性尝鲜版本,对于热衷尝试新特性的用户来说,推荐Current版本的Node.js。但是,Current版本中可能存在隐藏的Bug或者安全性漏洞,因此不推荐在企业七项目中使用Current版本低额node.js

安装:傻瓜式next,安装成功之后在终端验证是否安装成功,同时查看其版本号

运行Node.js

在node.js环境中执行JavaScript代码

1.打开终端

2.命令:node 要执行文件的存放路径

Node内置模块

fs文件系统模块

什么是fs文件系统

fs模块是node.js官方提供的,用来操作文件的模块,它提供了一系列的方法和属性,来满足用户对文件的操作需求

例如:

1.fs.readFile()方法,用来读取指定文件的内容

2.fs.writeFile()方法,用来向指定文件中写入内容

如果要在JavaScript代码中,使用fs模块来操作文件,则需要使用如下的方式先导入它:

疑问:只要我们安装了node.js,那么这边fs模块就是内置的,可以直接引入使用。

如何读取指定文件的内容

方法 说明
readFile 异步读取
readFileSync 同步读取
createReadStream 流式读取
fs.readFile() 异步读取

语法格式:

javascript 复制代码
fs.readFile(path[,options],callback)

path:必选参数,字符串,表示文件的路劲

options:可选参数,选线peu

callback:必选参数,文件读取完成后,通过回调函数拿到读取的结果,其中回调函数中接收两个参数,参数1是 读取问价失败的结果(是一个对象),参数2是读取文件成功的结果

实例代码:

1.读取成功时:

2.读取失败时:

此时err返回的是错误对象,dataStr则为undefine,因为文件读取失败了

3.总结:

当文件读取成功时,err的值为null,当文件读取失败时,则err的值为错误对象,dataStr的值为undefine,因为可以通过这个特征进行判断问价是否读取成功了。

fs. createReadStream**() 流式读取**

如何向指定文件中写入内容

fs.writeFile() 同步写入

语法:

javascript 复制代码
fs.writeFile(file,data[,options],callback)

path:必选参数,字符串,表示文件的路劲

data:必选参数,表示要写入的内容

options:可选参数,表示以什么编码对文件进行读取

callback:必选参数,文件读取完成后,通过回调函数拿到读取的结果,其中回调函数中接收一个参数,参数1是 读取问价失败的结果(是一个对象)

实例代码:

示例1

**注意:**当路径错误时,分两种情况

  • 绝对路径存在,会自动在指定路径下创建一个新的 文件,并写入指定内容,此时err为null
  • 绝对路径不存在,则err直接指向错误对象信息

示例2:

fs模块中的wirteFile方法写入文件的方式是异步的,向上面的例子是先指定了打印ok。

fs.writeFileSync() 异步写入

语法:

javascript 复制代码
fs.writeFileSync('./index.txt','test')
流式写入

适用场景:适合用于大文件写入或者频繁写入的场景,wirteFile适合写入频率较低的场景,因为其是一次性写入的。

ws保证了通道不断开,保持性输入,最后写完的时候使用ws.close()关闭通道即可(可选)

文件写入的应用场景

文件写入在计算机中算是一个非常常见的操作,下面的场景都用到了文件写入

  • 下载文件
  • 安装软件
  • 保存程序日志,如git
  • 编辑器保存文件
  • 视频录制

当需要持久化保存数据的时候,应该想到文件写入

练习

插入代码:

fs模块-路径动态拼接的问题

在使用fs模块操作文件时,如果提供的操作路径以./或者../开头的相对路径时,很容易出现路径动态凭借的错误问题。

原因:代码在运行的时候,会执行node命令所处的目录,动态拼接出被操作文件的完整路径。因为你执行node xx文件,虽然执行的是该文件,但是xx文件内部指向的目录是相对的,随着你的切换执行目录变而变,因此容易引发动态坪拼接的路径出错的问题。

解决:

1.使用绝对路径,即完整的存放路径,从而防止路径动态拼接的问题

缺点:移植性非常差,不利于维护

2.使用node.js提供的__dirname 表示当前文件所处的路径

path路径模块

path模块是node.js官方提供的、用来处理路径的模块。提供了一系列的方法和属性,用来满足用户对路径的处理需求

使用:const path=require('path')

API 说明
path.resolve 拼接规范绝对路径(用的比较多)
path.sep 获取操作系统的路径分隔符
path.pase 解析路径的基础名称
path.basename 获取路径的基础名称
path.dirname 获取路径的目录名
path.extname 获取路径的扩展名(.xxx)

path.join()

作用:用来将多个路径片段拼接成一个完整的路径字符串

语法:

javascript 复制代码
path.join([...path])

参数:

  • ...path:<string>路径片段的序列
  • 返回值:<string>

示例:

**注意:**涉及到路径的拼接操作,都要使用path.join()方法处理,避免直接使用+进行字符串拼接。因为使用+进行拼接的时候,比如你的拼接的路径中若带有./或者../的时候,直接使用+拼接容易出问题,而在join中,../和./是带有实际意义的,分别表示上层目录和当前目录

path.basename()方法

作用:用来从路径字符串中,将文件名解析出来。获取路径中最后一部分,通常通过这个方法获取路径中的文件名,语法格式如下:

语法:

javascript 复制代码
path.basename(path,[,ext])

参数:

  • path:必选参数,表示路径字符串
  • ext:可选参数,表示文件扩展名
  • 返回值:路径中最后一部分

HTTP协议

全称为Hypertext Transfer Protocol,即超文本传输协议,是互联网应用最广泛的协议之一

HTTP协议其实就是对浏览器和服务器之间的约束

主要相关的简介列出来,但是不做解释

创建一个http服务

javascript 复制代码
//1.导入htt模块
const http = require('http');

//2.创建服务对象
// createServer接收一个回到函数,同时该函数有两个参数,分别表示请求对象和响应对象
//request是请求报文的封装对象,借助这个对象我们可以获取客户端的一些请求信息
// response是对响应报文的封装对象,借助这个对象可以设置一些响应信息,例如响应头、响应体
//这个回调函数什么时候执行呢?当我们的服务接收到http请求的时候,则会执行

const server =http.createServer((request,response)=>{
  response.setHeader('Content-Type','text/html;charset=utf-8')//设置响应头,防止乱码
  response.end('hello http server,你好啊')
});

// 3.监听端口,启动服务
// 接收一个回调服务,这个回调函数在服务启动的时候执行
server.listen(9000,(err)=>{
  console.log('服务启动成功了,端口号为9000')
})

注意事项

1.命令行ctrl+c 停止服务

2.当服务器启动后,更新代码必须重启服务才能生效

3.响应内容中文乱码的解决方法

javascript 复制代码
response.setHeader('content-type','text/html;charset=utf-8')

4.端口号占用

javascript 复制代码
Error:listen EADDRINUSE:address already in use ::9000

1)关闭当前正在运行监听端口的服务(使用比较多的方式)

2)修改其他端口号

5.HTTP协议默认端口是80,其实这也是HTTP协议中的默认端口,开启的是默认端口时候,直接访问ip地址即可以向服务器发送请求,即端口号不会显示在url上。HTTP服务器开发常用的端口为3000,8080,9000等。

如果端口被其他程序占用,可以使用资源监视器找到占用端口的程序,然后使用任务管理器关闭对应程序

获取HTTP请求报文

想要获取请求的数据,需要通过request对象。要想返回浏览器想要的数据,即需要在请求报文中提取相应的数据信息。

含义 语法
请求方法 request.method
请求版本 request.httpVersion
请求路径 request.url
URL路径 require('url').parse(request.url).pathname
URL查询字符串 require('url').parse(request.url).query
请求头 request.headers
请求体 request.on('data',function(chunk){}) request.on('end',function(chunk){})

注意事项:

1.request.url只能获取路径以及查询字符串,不能获取URL中的域名以及协议的内容

2.request.headers将请求信息转成一个对象,并将属性名都转化成了【小写】

3.关于路径:如果访问网站的时候,只填写了IP地址或者是域名信息,此时请求路径为/

4.关于favicon.ico:这个请求是属于浏览器自动发送的请求

举例:

javascript 复制代码
const http = require('http');
const server =http.createServer((request,response)=>{
  response.setHeader('Content-Type','text/html;charset=utf-8')//设置响应头,防止乱码
  // // 获取请求体
  // 1.声明一个变量
  let body = ''
  // 2.注册一个监听函数,用来监听request的data事件
  request.on('data',(chunk)=>{
    // chunk是一个二进制数据,我们需要将其转换为字符串(内部会自动帮我将其转成字符串)
    body +=chunk.toString('utf-8')
  })
  // 3.注册一个监听函数,用来监听request的end事件(即可读的data数据读完了就会触发这个end事件)
  request.on('end',()=>{
    console.log(body)
    // 给浏览器做响应
    response.end('http')
  })
});
server.listen(9000,(err)=>{
  console.log('服务启动成功了,端口号为9000')
})
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <form action="http://127.0.0.1:9000" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="提交">
  </form>
</body>
</html>

联系示例

请求类型 请求地址 响应体结果
get /login 根据请求路径和请求类型,返回'登录页面''
get /reg 根据请求路径和请求类型,返回''注册页面''
javascript 复制代码
const http=require('http');
const server=http.createServer((request,response)=>{
  let {method} = request;
  let {pathname} = new URL(request.url,`http://${request.headers.host}`)
  response.setHeader('Content-Type','text/html;charset=utf-8')
  console.log(method,pathname)
  if(method==='GET' && pathname==='/login'){
    response.end('登录页面')
  }else if(method==='GET' && pathname==='/reg'){
    response.end('注册页面')
  }else{
    // 防止没有以上情况的时候,浏览器一直处于等待状态
    response.end('Not Found')
  }
})

server.listen(3000,()=>{
  console.log('服务器启动了...')
})

设置响应报文

作用 语法
设置响应状态码 response.statusCode
设置响应状态描述 response.statusMessage
设置响应头信息 response.setHeader('头名','头值')
设置响应体 response.write('xx')//每个请求允许有多个 response.end('xxx')//每个请求只允许有一个
javascript 复制代码
const http=require('http');
const server=http.createServer((request,response)=>{
  // 1.设置响应状态码(1xx---5xx)
  response.statusCode=200//默认是200
  // 2.设置响应状态描述
  response.statusMessage='OK'
  // 3.设置响应头
  response.setHeader('content-type','text/html;charset=utf-8')
  response.setHeader('Server','Node.js Server v1.0')
  // 4.响应体设置
  // 有两种方式:response.write()和response.end()
  // 其中end()方法是每个响应请求响应时必须要有一个end方法,且只能有一个,三是write允许有多个
  // 设置了writer之后同时也允许end,两者返回的响应体会合并返回给浏览器
  response.write('hello')
  response.end('response')
})

server.listen(3000,()=>{
  console.log('服务器启动了...')
})

Node.js模块化

什么是模块化

在 Node.js 中,模块化是一种将代码拆分为独立模块的机制,以实现代码的 复用、维护性和可扩展行。Node.js 使用了 CommonJS 模块规范来支持模块化。 模块化在 Node.js 中的基本原则是将代码划分为多个模块,每个模块都有自 己的作用域,并可以导出(export)一些功能供其他模块使用,同时也可以导入 (import)其他模块的功能来使用。 前端主要用到的模块方案:

  1. AMD:是 RequireJS 提出的一种模块化规范,主要用于浏览器环境下异步加 载模块。通过使用'define'函数来定义模块,使用'require'函数来异步加载依赖的 模块

  2. CommonJS:CommonJS 是一种模块化规范,主要用于服务端(如 Node.js)的 模块化开发。通过使用'module.exports'导出模块的功能吗,使用'reqiure'函数来 导入其他模块的功能。

  3. ES Modules(ESM):是 ECMAScript(ES6)引入的官方模块化规范,在现代浏览 器中广泛支持使用。通过使用'export'关键字导出模块的功能,使用'import'关键 字来导入其他模块的功能。

模块化的好处

1.防止命名冲突

  1. 高复用性

  2. 高维护

Node.js 中模块化的使用

下面是一些关于 Node.js 模块化的核心概念和用法:

  1. 导出模块:在一个模块中,通过 module.exports 或 exports 对象来导出模 块的功能。例如:
javascript 复制代码
// math.js
exports.add = function(a, b) { return a + b; };
// greeting.js
module.exports = 'Hello, World!'
  1. 导入模块:在另一个模块中,使用 require 函数来导入其他模块的功能。例 如:
javascript 复制代码
const math = require('./math.js');
console.log(math.add(2, 3)); // 输出 5
const greeting = require('./greeting.js');
console.log(greeting); // 输出 'Hello, World!'
  1. 导出和导入默认模块:除了导出具名的功能,还可以导出和导入默认模块。 默认模块只能导出一个默认功能,而不是一个对象。例如:
javascript 复制代码
// default.js
module.exports = function() {
console.log('This is the default function.');
};
// app.js
const defaultFunc = require('./default.js');
defaultFunc(); // 输出 'This is the default function.'
  1. 模块路径:模块路径是用于标识模块的字符串,可以是相对路径或者是 Node.js 内置模块或第三方模块的名称。例如:
javascript 复制代码
const fs = require('fs'); // 导入 Node.js 内置的 fs 模块
const lodash = require('lodash'); // 导入第三方模块 lodash
const myModule = require('./myModule'); // 导入相对路径为 './myModule' 的模块

require 使用的一些注意事项:

  1. 对于自己创建的模块,导入时路径建议写 相对路径 ,且不能省略 ./ 和 ../ 2. js 和 json 文件导入时可以不用写后缀 3. 如果导入其他类型的文件,会以 js 文件进行处理 4. 如果导入的路径是个文件夹,则会首先检测该文件夹下 package.json 文件 中 main 属性对应的文件,如果存在则导入,反之如果文件不存在会报错。如果 main 属性不存在,或者 package.json 不存在,则会尝试导入文件夹下的 index.js 和 index.json ,如果还是没找到,就会报错 5. 导入 node.js 内置模块时,直接 require 模块的名字即可,无需加 ./ 和 ../

框架

express

Express 是一个简洁而灵活的 node.js Web 应用框架, 提供一系列强大特性 帮助你创建各种 Web 应用。Express 不对 Node.js 已有的特性进行二次抽象, 我们只是在它之上扩展了 Web 应用所需的功能。丰富的 HTTP 工具以及来自 Connect 框架的中间件随取随用,创建强健、友好的 API 变得快速又简单。

理解:

◼ 我们前面用 http 模块来支持 web 服务,现在要用 express 来写 web 服务

◼ 对于 Node.js 来说,Express 是一个第三方模块,有丰富的 API 支持,强 大而灵活的中间件特性

◼ Express 不对 Node.js 已有的特性进行二次抽象,只是在它之上扩展了 Web 应用所需的基本功能

◼ 官方网站:https://expressjs.com/

Koa

Koa 框架是一个基于 Node 实现的 web 框架。对比于 Express 框架,丢弃了回调 函数,并有效地增强了异常处理。丢弃回调函数是因为 Koa 使用 Promise 配合 Async 函数实现异步,解决了 Node 回调地狱的问题。 它的设计理念和功能使 得开发者能够更高效地处理异步操作、构建模块化

理解:

◼ Koa 是一个 Node.js 的 Web 框架

◼使用了 ES6 的异步函数特性,以更优雅、简洁的方式来处理 HTTP 请求和 响应

Nest

Nest 是一个基于 Node.js 平台的框架,因此它是在 Node.js 环境下运行的。 它利用 Node.js 的特性和能力,以在 TypeScript 和 JavaScript (ES6、ES7、 ES8)之上构建高效、可伸缩的企业级服务器端应用程序,为开发者提供了更高 级别的抽象和工具,使得构建复杂的服务器端应用程序更加容易和高效。Nest 提 供了模块化架构、依赖注入、中间件支持、WebSocket 支持等功能,这些功能可 以帮助开发者组织和管理 Node.js 项目的代码结构,提高开发效率和代码可维 护性。

理解:

◼ 完美支持 Typescript

◼ 面向 AOP 编程

◼ 支持 Typeorm

◼ 高并发,异步非阻塞 IO

◼ Node.js 版的 spring

◼ 构建微服务应用

官方网站:https://nestjs.com/

相关推荐
Icoolkj1 分钟前
在 Windows 系统上升级 Node.js
windows·node.js
拉不动的猪2 分钟前
前端常见数组分析
前端·javascript·面试
小吕学编程19 分钟前
ES练习册
java·前端·elasticsearch
Asthenia041226 分钟前
Netty编解码器详解与实战
前端
袁煦丞31 分钟前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛2 小时前
vue组件间通信
前端·javascript·vue.js
一笑code2 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员2 小时前
layui时间范围
前端·javascript·layui
NoneCoder2 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19702 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端