Express简介(https://www.expressjs.com.cn/)
基于 Node.js 平台,快速、开放、极简的 Web 开发框架
安装
npm install express --save
HelloWorld
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
GET请求
const express = require('express')
const app = express()
const port = 3000
app.get('/user', (req, res) => {
res.send({
name:'leon',
age:18
})
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
POST请求
const express = require('express')
const app = express()
const port = 3000
app.post('/user', (req, res) => {
res.send({
name:'leon',
age:18
})
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
获取参数(http://localhost:3000/user?name=zq)
const express = require('express')
const app = express()
const port = 3000
app.get('/user', (req, res) => {
res.send(req.query)
})
app.listen(port, () => {
console.log(`app start on http://localhost:3000`)
})
动态参数(http://localhost:3000/user/zq/man)
const express = require('express')
const app = express()
const port = 3000
app.get('/user/:name/:sex', (req, res) => {
res.send(req.params)
})
app.listen(port, () => {
//请求方式http://localhost:3000/user/zq/man
console.log(`app start on http://localhost:3000/user/zq/man`)
})
托管静态资源
通过express.static()可以创建一个静态资源服务器。
例如,通过以下代码就可以把public目录下的资源对外开放
const express = require('express')
const app = express()
app.use(express.static('public'))
// 可以托管多个静态资源
app.use(express.static('static'))
// 增加路径前缀
app.use('clock',express.static('./public/clock'))
app.listen(3000,()=>{
console.log('app start on http://localhost:3000')
})
express中的路由
在express中,路由是指客户端的请求和服务器处理函数之间的映射关系。
express路由由3部分组成,请求的类型,请求的url路径以及处理的函数,格式如下:
app.METHOD(PATH,HANDLER)
简单用法
app.get('/user', (req, res) => {
res.send({
name:'leon',
age:18
})
})
模块化路由
为了方便对路由的模块化管理,express不建议把路由直接挂载在到app上。而是推荐把路由抽离成单独的模块。
抽离路由为单独模块的步骤如下:
- 创建路由模块对应的js文件
- 调用express.Router()函数创建路由对象
- 向路由对象挂在具体的路由
- 使用module.exports()向外暴露路由对象
- 使用app.use函数注册路由对象
### router.js
// 1.导入express
var express = require('express');
// 2.创建路由对象
var router = express.Router();
// 3.创建具体的路由
router.get('/user',(req,res)=>{
res.send(req.query)
})
router.post('/list',(req,res)=>{
res.send(req.query)
})
module.exports = router;
### index.js
const express = require('express');
var router = require('./router')
const app = express()
const port = 3000
//增加前缀
app.use('/api',router)
app.listen(port, () => {
console.log(`app start on http://localhost:3000`)
})
Express中间件(Middleware)
特指业务流程的中间处理环节
![在这里插入图片描述](https://img-blog.csdnimg.cn/60ac1230d0664277bcb89075f2e8d178.png)
Express中间件的调用流程
当一个请求到达Express服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
![在这里插入图片描述](https://img-blog.csdnimg.cn/3299b6bf84ee457abb0a03b19ad43ec5.png)
express中间件的格式
本质上就是一个function的处理函数
app.get('/',function(req,res,next){
next()
})
next()函数是实现中间件的关键函数,它实现了中间件的连续调用,并把业务转交给下一个中间件或者路由。
全局中间件
客户端发起的任何请求,到达服务器后,都会触发的中间件叫全局中间件
通过调用app.use(全局中间件),可以创建一个全局中间件示例代码如下:
var express = require('express');
var app = express();
var mw = function(req,res,next){
console.log("全局中间件")
next();
}
app.use(mw)
// 简写形式
app.use(function(req,res,next){
console.log("全局中间件-简写形式")
next();
})
app.get('/',(req,res,next)=>{
res.send("请求后台成功")
})
app.listen(3000,()=>{
console.log("start on 127.0.0.1:3000")
})
局部中间件
不使用app.user()注册的中间件都是局部中间件
// 局部生效的中间件,不使用app.use()的中间件都是局部生效的中间件
var mv1 = function(req,res,next){
console.log("局部生效的中间件")
next()
}
app.get('/',mv1,(req,res,next)=>{
res.send("请求后台222成功")
})
app.get('/ts',function(req,res,next){
console.log("匿名函数简写方式")
next()
},(req,res,next)=>{
res.send("请求后台222成功")
})
中间件的注意事项
- 中间件一定要写在调用路由之前,否则中间不生效
- 中间件可以连续调用
3.中间件最后一定要写next,并且next之后就不需要写代码防止业务逻辑混乱
4.连续调用多个中间件时,中间件之间共用同一份req和res
express中间件的分类
- 应用级别的中间件
- 路由级别的中间件
- 错误级别的中间件
- 内置级别的中间件
- 第三方的中间件
应用级别的中间件
通过app.use或者app.get和app.post注册使用的中间件属于应用级别的中间件
路由级别的中间件
通过绑定在express.Router()实例上的中间件属于路由级别的中间件
错误级别的中间件
用来捕获项目中发生的异常错误,从而防止项目异常崩溃的问题
参数是(err,req,res,next)
注意!!!错误中间件必须注册在所有路由之后方可生效
express内置的中间件
- express.static()
- express.json()
- express.urlencoded()
var express = require('express');
var app = express();
// 演示内置中间件的使用
// express.json
app.use(express.json())
app.use(express.urlencoded({extended:false}))
app.post('/user',(req,res)=>{
// req.body服务器用来接收客户端传来的请求体数据
// 如果没有配置解析表单数据的中间件,req,body默认是undefined
console.log(req.body)
res.send(req.body)
})
// express.urlencoded()
app.post('/book',(req,res)=>{
// req.body服务器用来接收客户端传来的请求体数据
// 如果没有配置解析表单数据的中间件,req.body默认是{}
console.log(req.body)
res.send(req.body)
})
app.listen(3000,()=>{
console.log("start on 127.0.0.1:3000")
})
第三方中间件
var express = require('express');
var qs = require('querystring')
var app = express();
// 演示创建自定义中间件
// 模拟内置模块express.urlencded()功能
var encoded = function(req,res,next){
// 获取data数据
// 由于data数据有时候过大,服务器会截取一部分一部分传输过来
// 所以我们需要监听data事件拼接数据
let str = "";
req.on('data',(chunk)=>{
str += chunk;
})
// 数据传输完毕,监听end事件
req.on('end',()=>{
// 调用express内置模块queryString解析字符串
req.body=qs.parse(str)
next()
})
}
app.use(encoded)
app.post('/',(req,res)=>{
res.send(req.body)
})
app.listen(3000,()=>{
console.log("start on 127.0.0.1:3000")
})
解决跨域问题
cors方式(主流)
- 运行npm install cors (安装中间件)
- var cors = require(‘cors’) (导入中间件)
- app.use(cors) (注册全局中间件)
什么是cors
CORS(Cross-origin-Resource-Sharing,跨域资源共享)由一系列HTTP响应头组成,这些HTTP响应头决定是否组织前端JS代码跨域获取资源。
cors三个请求头
- Access-Control-Allow-Headers
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
cors请求两大类
简单请求:1.get,post,head三种请求方式之一
2.HTTP头部信息不包括默认字段
预检请求:1.get,post,head三种请求方式之外
2.自定义头部字段
3.向服务器发送了application/json格式的数据
const cors = require('cors')
app.use(cors())
app.use((req,res,next)=>{
res.setHeader("Access-Control-Allow-Origin","*")
res.setHeader("Access-Control-Allow-Headers","Content-Type,X-Custom-Header")
res.setHeader("Access-Control-Allow-Methods","POST,GET,DELETE,HEAD")
next()
})
什么是预检请求
浏览器和服务器正式通讯之前,浏览器会先向服务器发送一个option的请求以预检,以获知服务器是否允许该实际请求。服务器成功响应后,浏览器才会向服务器发送真正的请求并携带真实数据。
JSONP
概念:浏览器通过<script>标签的src属性,请求服务器上的数据,同时,服务器返回一个函数调用。这种请求方式就叫JSONP。
1.JSONP不属于真正的ajax请求,因为它没使用XMLHttpRequest这个对象
2.JSONP仅支持GET请求。