Node.Js(二)

express中间件

express的中间件本质上就是一个function处理函数

const express = require('express')
const app = express();

app.get('/',function(req,res.next){
    
    
	next()
})

注:中间件函数的形参列表中,必须包含next参数,而路由处理函数中只包含req,res参数

next()函数是实现多个中间件连续调用的关键,他表示把流转关系转交给下一个中间件或路由

全局 生效的中间件:

使用app.use()定义的中间件

局部生效的中间件:

不使用app.use()定义的中间件

定义多个局部中间件:

//以下两种写法是"“完全等价"的,可根据自己的喜好,选择任意一种方式进行使用 app.get( ‘/’ ,mw1,mw2,(req,
res) => { res.send( " Home page.”) app.get( ‘/’,[mw1,mw2],(req,res) =>
{ res.send( ’ Home page."))

中间件的注意事项:

1.一定要在路由之前注册中间件
2.客户端发送过来的请求,可以连续调用多个中间件进行处理
3.执行完中间件的业务代码之后,不要忘记调用next)函数
4.为了防止代码逻辑混乱,调用next(函数后不要再写额外的代码连续调5.用多个中间件时,多个中间件之间,共享req和res对象

中间件的分类:

  • 路由级别的中间件:
    绑定到express.Router()实例上的中间件,叫做路由级别的中间件

    var app = express()
    var router = app.Router()
    
    router.use(function(req,res,next){
          
          
    	console.log('Time',Date.new())
    	next()
    })
    
    app.use('/',router)
    
  • 应用级别的中间件:

    通过app.use()或者app.get()或app.post(),绑定到app实例上的中间件,叫做应用级别的中间件

    //应用级别的中间件(全局中间件)
    app.use((req,res,next)=>{
          
          
    	next()
    })
    
    //应用级别的中间件(局部中间件)
    app.get('/',nm,(req,res)=>{
          
          
    	res.send('home page')
    })
    
  • 错误级别的中间件

    错误级别中间件的作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
    **格式:**错误级别中间件的 function处理函数中,必须有4个形参,形参顺序从前到后,分别是(err, req, res, next)。

    app.get( ' /", function (req,res) {
          
            //路由
    	throw new Error("服务器内部发生了错误!')//抛出一个自定义的误
    	res.send( "Home Page")
    })
    
     app.use(function (err, req,res,next){
          
          //错汉极励的中问件
         console.log( "发生了错误: ' +err.message)
    // 在服务器打印消息
    	res.send('Error! ' + err.message)//向客户靠家应错误相关的内容
     })
    
    

    注:要把错误级别的中间件放在全部路由之后

express内置的中间件

express.static 快速托管静态资源的内置中间件,例如:HTML

文件、图片、CSS样式等(无兼容性)

express.json解析JSON格式的请求体数据(有兼容性,仅在

4.16.0+版本中可用)

express.urlencoded 解析URL-encoded格式的请求体数据(有

兼容性,仅在4.16.0版本中可用)

//配置解析application/json格式敖据的内置中问件 app.use( express.json(o)
//配置解析application/x-www-form-urlencoded格式数据的内置中间件
app.use(express.urlencoded({ extended: false }

第三方的中间件

非 Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以按需下载并配置第三方中间件,从而提高项目的开发效率。

以使用body-parser这个第三方中间件为演示步骤:

运行npm install body-parser安装中间件

使用require 导入中间件

调用app.use()注册并使用中间件

自定义中间件

实现步骤:

  • 定义中间件
  • 监听req的data事件
  • 监听req的end事件
  • 使用querystring模块解析请求体数据
  • 将解析出来的数据对象挂载为req.body
  • 将自定义中间件封装为模块
  1. 定义中间件

    app.use(function(req.res,next) {
          
          
        //中间件的业务逻辑
    })
    
    
  2. 监听req的data事件

    //定义变量。用来存储名户读发送过来的请求体数据
    let str = " "
    //监听req对象的 data 事件(客户读发试过来的新的清求体数购)
    req.on( ‘data' , (chunk)=>i
    //拼接请求体数据,转换为宁符串
    str += chunk
    
    
  3. 监听req的end事件

    //监听req对象的end 事件(请求体发送完毕后自动触发)
    req.on( " end",()=>{
          
          
    	//打印完整的请求体数据
    	console.log(str)
    //TOD0:把字符串格式的请求体数据,解析成对象格式
    }
    
  4. 使用querystring模块解析请求体数据

    //导入处理querystring的 Node.js内置模块
    const qs = require( " querystring " )
    //调用qs.parse()方法,把查询字符串解析为对象
    const body = qs.parse(str)
    
    
  5. 将解析出来的数据对象挂载为req.body

    req.on( " end' , ()> {
          
          
    	const body = qs.parse(str)  // 调用qs.parse()方法,把查询字符串解断为对象
    	req.body = body  //将解析出来的清求体对象。挂载为req.body属性
    	next()   //最后,一定要调用next()函数,执行后续的业务逻辑
    })
    
    
  6. 将自定义中间件封装为模块

    编写接口

    使用express编写接口

    1.创建一个服务器

    const express = require('express')
    
    const app = express()
    
    app.listen(80,()=>{
          
          
    	conlose.log('http://127.0.0.1')
    })
    

    2.创建API路由模块

    // apiRouter.js【路由模块】
    const express - require( " express ')
    const apiRouter = express.Routero
    
    // bind your router here.. .
    
    
    module.exports = apiRouter
    
    // app.js 【导入并注册路由模块】
    const apiRouter = require( " ./apiRouter.js ")
    
    app.use( ' /api ' , apiRouter)
    
    

    解决跨域问题:

    解决接口跨域问题的方案主要有两种:

    CORS(主流的解决方案,推荐使用)
    JSONP(有缺陷的解决方案:只支持GET请求)

使用cors中间件解决跨域问题:

cors 是Express的一个第三方中间件。通过安装和配置cors中间件,可以很方便地解决跨域问题。使用步骤分为如下3:
1.运行npm install cors安装中间件

2.使用const cors = require("cors')导入中间件

3在路由之前调用app.use(cors0)配置中间件

CORS跨域资源共享

  • CORS响应头部-Access-Control-Allow-Origin

响应头部中可以携带一个Access-Control-Allow-Origin字段,其语法如下:
Access-Control-Allow-Origin: l*
其中,origin参数的值指定了允许访问该资源的外域URL。 例如,下面的字段值将只允许来自http://itcast.cn 的请求:
res.setHeader( ’ Access-Control-Allow-Origin" , "http:llitcast.cn’)

 如果指定了Access-Control-Allow-Origin字段的值为通配符*,表示允许来自任何域的请求,示例代码如下:
  res.setHeader( ' Access-Control-Allow-Origin" , "*")
  • Access-Control-Allow-Headers

默认情况下,CORS仅支持客户端向服务器发送如下的9个请求头:
Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width ,Content-Type(值仅限于text/plain、multipart/form-data、application/x-www-form-urlencoded三者之一)
如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过Access-Control-Allow-Headers
对额外的请求头进行声明。否则这次请求会失败!
//允许客户端额外向服务器发送Content-Type请求头和X-Custom-Header请求头 //注意;多个请求头之间使用英文的运号进行分割 3 res.setHeader( ’
Access-Control-Allow-Headers’,‘Content-Type’,'X-Custom-Header ')

  • Access-Control-Allow-Methods

默认情况下,CORS仅支持客户端发起GET、POST、HEAD请求。
如果客户端希望通过PUT、DELETE等方式请求服务器的资源,则需要在服务器端,通过Access-Control-Alow-Methods来指明实际请求所允许使用的
HITP方法。 示例代码如下:
//只允许POST、GET、DELETE、HEAD请求方法 res.setHeader( " Access-Control-Allow-Methods’,"POST,GET,DELETE,HEAD’)
//允许所有的HTTP请求方法 res.setHeader( " Access-control-Allow-Methods " , "*')

cors请求

  • 简单请求

同时满足以下两大条件的请求,就属于简单请求:
请求方式:GET、POST、HEAD三者之一
HTTP头部信息不超过以下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、DPR.Downlink、Save-Data、Viewport-Width、Width 、Content-Type(只有三个值application/x-www-form-
urlencoded、multipart/form-data、text/plain)

  • 预检请求

只要符合以下任何一个条件的请求,都需要进行预检请求:
请求方式为GET、POST、HEAD之外的请求
Method类型请求头中包含自定义头部字段
向服务器发送了application/json格式的数据
在浏览器与服务器正式通信之前,浏览器会先发送OPTION请求进行预检,以获知服务器是否允许该实际请求,所以这一次的OPTION请求称为“预检请求”。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据.

简单请求和预检请求的区别:

简单请求的特点:客户端与服务器之间只会发生一次请求。
预检请求的特点:客户端与服务器之间会发生两次请求,OPTION预检请求成功之后,才会发起真正的请求

JSONP接口

概念:浏览器端通过

特点:1.JSONP不属于真正的Ajax请求,因为它没有使用XMLHttpRequest这个对象。

2.JSONP仅支持GET请求。不支持POST、PUT、DELETE 等请求。

创建JSONP接口的注意事项:
如果项目中已经配置了CORS跨域资源共享,为了防止冲突,必须在配置CORS中间件之前声明JSONP的接口。否则JSONP接口会被处理成开启了CORS的接口。示例代码如下:

//优先创建JsONP接口【[这个接口不会被处理成CORS接口】

 app.get( " /api/jsonp ' . (req, res) =>{
    
    })

//再配置CORS中问件【后续的所有接口,都会帔处理成CORS 接口】

 app.use(cors()//这是一个开启了CORS 的接口
sapp.get( " /api/get". (req. res) =>{
    
     }

实现JSONP接口额步骤:

1.获取客户端发送过来的回调函数的名字

const functionName = req.query.callback

2.得到要通过JSONP形式发送给客户端的数据

3.根据前两步得到的数据,拼接出一个函数调用的字符串

4.把上一步拼接得到的字符串,响应给客户端的

猜你喜欢

转载自blog.csdn.net/m0_63679126/article/details/125473602