“我报名参加金石计划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')
})
注意事项
- 要在路由之前注册中间件
- 客户端发送的请求可连续调用多个中间件
- 不要忘记调用next()函数
- 调用next()后不要再写代码
- 多个中间件共享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}))
第三方中间件
- npm i 下载
- require导入
- 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','*')
简单请求与预检请求
简单请求
- 请求方式:GET,POST,HEAD之一
- HTTP头部信息不超过九种字段,无自定义头部字段
预检请求
符合以下任一条件
- 请求方式为GET,POST,HEAD之外的请求类型
- 请求头包含自定义头部字段
- 向服务器发送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)
})