- Node.js是一个JavaScript的后端运行环境,无法调用Ajax、DOM和BOM等浏览器内置API。
Node.js仅仅提供了基础的功能和API,但是基于这些基础功能,开发了各种框架。 - node.js框架
Express.js是快速开发web应用程序,因为它具有强大的路由、模板、安全功能和错误处理规定,可以将其用于企业级开发。Koa.js是Express框架的扩展,具有新功能,并且错误处理能力要好得多,依然享受Express的灵活性和更多的自由度和更少的复杂性。Fastify是灵感来源于Hapi和express的web框架,致力于最少的开销和强大的插件结构提供最佳的开发体验。Egg.js为企业级框架和应用而生的,继承了Koa.js的高性能优点,又加入了一些约束规范来避免Koa.js自由度太高导致的问题,不同于Express、Koa等应用级的提炼封装,使其更贴近业务场景,更快上手。 - Express
(1)可以构建单页和多页的web应用程序
(2)高性能,使用异步编程相互独立地执行多个操作
(3)具有许多Node.js功能作为函数,并用很少的代码加快进程
(4)支持14+引擎模板和HTTP方法 - path路径模块
path模块是Node.js官方提供的、用来处理路径的模块。
引入path模块:const path = require('path')
path.join()方法,用来将多个路径片段拼接成一个完整的路径字符串
path.basename() 方法,用来从路径字符串中,将文件名解析出来
path.extname() 方法,用来从路径字符串中,将文件后缀解析出来 - http模块
http模块是Node.js 官方提供的、用来创建web服务器的模块。通过http模块提供的http.createServer()方法,就能方便的把一台普通的电脑,变成一台Web服务器,从而对外提供Web资源服务。 - 根据不同URL相应不同html内容
①获取请求的url地址
②设置默认的响应内容为404 Not found
③判断用户请求的是否为/或/index.html首页
④判断用户请求的是否为/about.html关于页面
⑤设置Content-Type响应头,防止中文乱码
⑥使用res.end()把内容响应给客户端
- node.js中的模块分类
●内置模块(内置模块是由Node.js官方提供的,例如fs、 path. http等)
●自定义模块(用户创建的每个js文件,都是自定义模块)
●第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载),又称为包 - 加载模块:const 名字 = require()
- 模块作用域
在自定义模块中定义的变量、方法等只能在当前模块内被访问,可以向外共享module.exports,默认值为{}
默认情况下,export和module.exports指向同一个对象,但最终共享的结果还是module.exports指向的对象为准。 - npm
初次装包,多了个node_modules的文件夹和package-lock.json - node_modules
存放所有已安装到项目的包,require的时候就是在这个目录里面找 - package-lock.json
记录下载的每一个包的信息,比如包的名字、版本号、下载地址等 - package.json
记录跟项目相关的信息:项目的名称、版本号、包的名字、使用阶段(开发、部署期间),里面有个dependencies节点,专门记录用npm install 安装了什么包 - 包的分类
开发依赖包(被记录到devDependencies节点中的包,只在开发期间会用到) -D
核心依赖包(被记录到dependencies节点中的包,在开发期间和项目上线之后都会用到)
------------------------------------------
npm i 包名 -g:全局安装
只有工具性质的包,才有全局安装的必要性,可以参考官方提供的使用说明 - 规范的包的组成结构
(1)包必须以单独目录而存在
(2)包的顶级目录下要必须包含package.json这个包管理配置文件
(3)package.json中必须包含name,version,main这三个属性,分别代表包的名字、版本号、包的入口

- 模块的加载机制
- 优先从缓存里加载
- 内置模块的加载优先级最快的,即使node_modules目录下有名字相同的包
- 自定义模块:必须以./或../开头,不然node会把它当做内置模块或第三方模块加载
没写文件的扩展名加载的顺序:按名字加载->补全.js加载->补全.json加载->补全.node加载->加载失败,终端报错 - 第三方模块:如果不是内置模块,也没有以./或../开头,就会去node_modules文件夹加载第三方模块,如果没有找到,则移动到上一层父目录进行加载,直到文件系统的根目录
- 目录作为模块
①在被加载的目录下查找一个叫做package.json的文件,并寻找main属性,作为require()加载的入口
②如果目录里没有package.json文件,或者main入口不存在或无法解析,则Node,js将会试图加载目录下的index.js文件
③如果以上两步都失败了,则Node.js会在终端打印错误消息,报告模块的缺失: Error: Cannot find module 'xx' - Express框架:快速搭建Web网站的服务器或API接口的服务器
Web网站服务器:专门对外提供Web网页资源的服务器
API接口服务器:专门对外提供API接口的服务器 - 用express搭建web服务器
const express = require('express') const app = express() app.listen(80,()=>{ console.log('express server running at http://127.0.0.1:80'); }) // query app.get('/',(req,res)=>{ res.send(req.query) }) // params app.get('/user/:id/:name',(req,res)=>{ res.send(req.params) })
- nodemon 会监听项目文件变动,自动帮我们重启项目,极大方便了开发和调试
- express路由:包括请求类型、url地址、处理函数
- 模块化路由
①创建路由模块对应的js文件
②调用express.Router(函数创建路由对象)
③向路由对象上挂载具体的路由
④使用module.exports向外共享路由对象
⑤使用app.use()函数注册路由模块// 创建路由模块 const express = require('express') const router = express.Router() router.get('/user/list',(req,res)=>{ res.send('Get user list.') }) router.post('/user/add',(req,res)=>{ res.send('Add new user.') }) module.exports = router // 将路由模块挂载到app上 const router = require('./router.js') app.use(router) // 添加访问前缀 app.use('/hh',router) - 中间件的分类
- 应用级别的中间件,绑定到APP实例上的
- 全局中间件:客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。
通过调用app.use(中间件函数),即可定义一个全局生效的中间件。const mw = function(req,res,next){ next() } app.use(mw) // 简化形式-------------------- app.use((req,res,next)=>{ next() }) - 局部中间件
const mw1 = function(req,res,next){ next() } const mw2 = function(req,res,next){ next() } app.get('/',mw1,mw2,(req,res)=>{ res.send('hhh') }) // 或 app.get('/',[mw1,mw2],(req,res)=>{ res.send('hhh') })
- 全局中间件:客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。
- 路由级别的中间件
绑定到express.Router()实例上的中间件,用法与应用级别的中间件没区别。 - 错误级别的中间件
专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题,必须注册在所有路由之后app.get('/user',(req,res)=>{ throw new Error('error') }) app.use((err,req,res,next)=>{ res.send('Error:'+err.message) }) - Express内置的中间件
常用的:express.json:解析JSON格式的请求体数据;express.urlencoded:解析URL-encoded格式的请求体数据 - 第三方的中间件
- 自定义中间件
- 应用级别的中间件,绑定到APP实例上的
- 中间件注意事项
①一定要在路由之前注册中间件
②客户端发送过来的请求,可以连续调用多个中间件进行处理
③执行完中间件的业务代码之后,不要忘记调用next()函数
④为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码
⑤连续调用多个中间件时,多个中间件之间,共享req和res对象 - 身份认证
对于服务端渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:
①服务端渲染推荐使用 Session认证机制
②前后端分离推荐使用JWT认证机制 -
HTTP的无状态性:每次HTTP请求是独立的,连续多个请求之间没有直接关系,服务器不会主动保留每次HTTP请求的状态
-
Cookie
是存储在浏览器的一段字符串,由一个名称、一个值和其他几个用于控制Cookie有效期、安全性、使用范围的可选属性组成的。不同域名下的Cookie相互独立,当客户端发起请求时,会自动把当前域名下所有未过期的Cookie一同发送到服务器。
特性:自动发送、域名独立、过期时限、4KB限制 -
Cookie在身份认证中的作用
客户端第一次请求服务器的时候, 服务器通过响应头的形式,向客户端发送一个身份认证的Cookie,客户端会自动将Cookie保存在浏览器中。
随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的Cookie,通过请求头的形式发送给服务器,服务器即可验明客户端的身份。
由于Cookie是存储在浏览器中的,而且浏览器也提供了读写Cookie的API,因此Cookie很容易被伪造,不具有安全性。因此不建议服务器将重要的隐私数据,通过Cookie的形式发送给浏览器。 -
Session认证机制需要配合Cookie才能实现,但Cookie默认不支持跨域访问,所以当前端跨域请求接口的时候,需要额外配置
-
JWT:跨域认证解决方案
工作原理:客户端将账号密码发送给服务器,服务器认证通过后生成token返回给客户端,客户端将token存储在localstorage或者sessionStorage里面,当客户端发送请求时,通过请求头的Authorization字段将token发送给服务器,服务器还原验证后,将当前用户的请求内容返回给客户端 -
JWT的组成部分:Header.Payload.Signature
Payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。
Header 和Signature是安全性相关的部分,只是为了保证Token的安全性。
【Cxinny】node.js
本文介绍了Node.js的后端开发环境特点,强调它不能直接调用浏览器API。接着详细讨论了几个流行的Node.js框架,如Express.js的快速应用开发特性,Koa.js对Express的扩展以及更好的错误处理,Fastify的低开销和插件架构,以及Egg.js针对企业级开发的优化。此外,还涵盖了HTTP模块、模块系统、npm包管理、中间件机制以及身份认证策略,包括Session和JWT的使用。

被折叠的 条评论
为什么被折叠?



