Node.Js(二)

简介: 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.把上一步拼接得到的字符串,响应给客户端的


目录
相关文章
|
9月前
|
JavaScript 网络协议
Node.js
fs模块 文件写入 writeFile 异步写入 writeFileSync 同步写入 appendFile / appendFileSync 追加写入 createWriteStream 流式写入 文件读取 readFile 异步读取 readFileSync 同步读取 createReadStream 流式读取 文件移动与重命名 文件删除 文件夹操作 mkdir 创建文件夹 readdir 读取文件夹 rmdir 删除文件夹 查看资源状态 path模块
58 1
|
4天前
|
JavaScript 前端开发 容器
初识node.js(使用)
初识node.js(使用)
25 7
|
4天前
|
JSON JavaScript 前端开发
Node.js 的适用场景
Node.js 的适用场景
36 0
|
8月前
|
JavaScript 安全 前端开发
Node.js 20.6.0 特点
Node.js 20.6.0 特点
|
11月前
|
Web App开发 JavaScript 前端开发
Node.js 是什么?
Node.js 是什么?
|
11月前
|
SQL 存储 JavaScript
【Node.js】初识Node.js
【Node.js】初识Node.js
|
缓存 运维 JavaScript
狼叔:聊聊 Node.js
前阵子我在知乎上回答了《2021前端会有什么新的变化?》,单篇33.8万的阅读量,还是不错的,说明大家非常关心前端的变化趋势,这里再与大家分享一下我对 Node.js 相关内容的看法。
狼叔:聊聊 Node.js
|
机器学习/深度学习 Kubernetes JavaScript
Node.js 要完了吗?
不管你输入的是哪种技术都可以搜出来一大堆文章来,其中很多无疑写的就是垃圾。就算是 Kubernetes 之类的新技术也不能幸免,Node.js 自然也不例外。
|
JavaScript 前端开发
Node.js的特点
作为后端JavaScript的运行平台,Node保留了前端JavaScript中些熟悉的接口,没有改写语言本身的任何特性,依旧基于作用域和原型链,区别在于它将前端中广泛应用的思想作用到了服务器端。下面我们来看看Node相对于其他语言的一些特点。
1345 0
|
Web App开发 JavaScript 前端开发