node.js(二) - Express

130 阅读5分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情

Express

Express是基于nodejs的Web开发框架,专门用来创建Web服务器

创建基本的web服务器

// 导入
const express = require('express')
// 创建web服务器
const app = express()
// 启动
app.listen(80,() => {
    console.log("Express success http://127.0.0.1");
})

监听请求

app.get('url',(req,res) => {})
app.post('url',(req,res) => {})

响应数据给客户端

res.send()
app.get('/user',(req,res) => {
    res.send({name:"狗子",age:18})
})

app.get('/user',(req,res) => {
    res.send('post success')
})

获取url携带的查询参数

req.query

获取url获取动态参数

req.params
app.get('/user/:id',(req,res) => {
    res.send(req.params)
})

托管静态资源

express.static()
//访问public目录下的所有文件
app.use(express.static(public))
//访问路径 http://localhost:3000/images/xxx
//挂载路径前缀
app.use('/public',express.static(public))
//访问路径 http://localhost:3000/public/images/xxx

路由

指客户端的请求与服务器处理函数之间的映射关系

express中的路由分为三部分,分别是请求类型,URL地址,处理函数

app.method(path,handle)

模块化路由

创建路由模块对应的js文件

模块化路由.js
router.js

调用express.Router()创建路由对象

//router.js
const express = require('express')

const router = express.Router()

向路由对象上挂载具体的路由

//router.js
router.get('/user/list',(req,res) => {
    res.send('getUserList')
})

router.post('/user/add',(req,res) => {
    res.send('addUser')
})

使用module.exports导出共享路由对象

//router.js
module.exports = router

调用app.use()函数注册路由模块

//模块化路由.js
const express = require('express')
const userRouter = require('./08_router')

const app = express()
//无前缀
app.use(userRouter)
//为路由模块添加前缀
app.use('/api',userRouter)
app.listen(80,() => {
    console.log('http://127.0.0.1');
})

中间件

调用流程

当一个请求到达Express的服务器后,可以连续调用多个中间件,对这次请求进行预处理

中间件格式

本质就是一个function处理函数,中间件函数的形参列表中,必须包含next参数,而路由处理函数中只包含req和res

const mw = function(req,res,next){
    console.log('我是中间件');
    next();
}
next函数的作用

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

全局生效的中间件

任何请求到达服务器后都会触发的中间件叫做全局生效的中间件

//定义一个全局生效的中间件
const mw = function(req,res,next){
    console.log('我是中间件');
    next();
}
app.use(mw)

中间件的作用

多个中间件共享一份req和res,上游中间件可以为req和res添加自定义的属性或方法,供下游的中间件或路由进行使用

局部生效的中间件

const mw = function(req,res,next){
    console.log('我是中间件');
    next();
}
// mw中间件局部生效
app.get('/',mw,(req,res) => {
    res.send('Home')
})

app.get('/user',(req,res) => {
    res.send('user')
})

注意事项

  1. 要在路由之前注册中间件
  2. 客户端发送的请求可连续调用多个中间件
  3. 不要忘记调用next()函数
  4. 调用next()后不要再写代码
  5. 多个中间件共享req和res

中间件的分类

应用级别中间件

通过app.use app.get app.post绑定到app实例上的中间件

路由级别中间件

绑定到express.Router()实例上的中间件

错误级别中间件

专门用来捕获整个项目中发生的异常错误,防止项目一场崩溃的中间件

注册在所有路由之后

function(err,req,res,next){}

Express内置中间件

//托管静态资源
express.static()
//解析json格式的请求体数据
express.json()    4.16.0+
//获取请求体数据
req.body
//配置
app.use(express.json())
//解析URL-encoded格式的请求体数据
express.urlencoded()	4.16.0+
//配置
app.use(express.urlencoded({extended:false}))

第三方中间件

  1. npm i 下载
  2. require导入
  3. app.use注册

自定义中间件

解决跨域

CORS(推荐)

CORS由一系列HTTP响应头组成,决定浏览器是否阻止前端js代码跨域获取资源

//安装中间件
npm install cors
//导入
const cors = require('cors')
//在路由之前调用
app.use(cors())

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

//origin参数指定了允许访问该资源的外域URL
Access-Control-Allow-Origin:<origin> | *
//允许任何域的请求
res.setHeader('Access-Control-Allow-Origin','*')

CORS响应头部 - Access-Control-Allow-Headers

默认CORS仅支持客户端向服务器发送九个请求头

如果发送了额外的请求头,需要早服务器端,通过Access-Control-Allow-Headers对额外的请求头声明,否则请求失败

CORS响应头部 - Access-Control-Allow-Methods

默认CORS仅支持客户端发起GET,POST,HEAD请求

如果客户端希望通过PUT,DELETE等方式发送请求,需要在服务端指明实际请求所允许使用的HTTP方法

res.setHeader('Access-Control-Allow-Methods','POST,GET,DELETE,HEAD')

res.setHeader('Access-Control-Allow-Methods','*')

简单请求与预检请求

简单请求
  1. 请求方式:GET,POST,HEAD之一
  2. HTTP头部信息不超过九种字段,无自定义头部字段
预检请求

符合以下任一条件

  1. 请求方式为GET,POST,HEAD之外的请求类型
  2. 请求头包含自定义头部字段
  3. 向服务器发送applocation/json格式的数据
区别

简单请求:客户端与服务器之会发生一次请求

预检请求:客户端与服务器之会发生两次请求,OPTION预检请求成功之后才会发起真正的请求

JSONP(只支持GET请求)

必须在配置CORS之前配置JSONP接口

实现JSONP接口

app.get('/api/jsonp',(req,res) => {
	1.得到函数名称
	const funcName = req.query.callback;
	2.定义要发送到客户端的数据对象
	const data = {name:'a',age:10}
	3.拼接出函数的调用
	const scriptStr = `${funcName}(${JSON.stringfy(data)})`
	4.把拼接的字符串响应给客户端
	res.send(scriptStr)
})