【Cxinny】node.js

本文介绍了Node.js的后端开发环境特点,强调它不能直接调用浏览器API。接着详细讨论了几个流行的Node.js框架,如Express.js的快速应用开发特性,Koa.js对Express的扩展以及更好的错误处理,Fastify的低开销和插件架构,以及Egg.js针对企业级开发的优化。此外,还涵盖了HTTP模块、模块系统、npm包管理、中间件机制以及身份认证策略,包括Session和JWT的使用。
  • 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格式的请求体数据
    • 第三方的中间件
    • 自定义中间件
  • 中间件注意事项
    ①一定要在路由之前注册中间件
    ②客户端发送过来的请求,可以连续调用多个中间件进行处理
    ③执行完中间件的业务代码之后,不要忘记调用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的安全性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值