一、use使用中间件
1.功能
- (1)使用第三方插件
- (2)作为路由的全局守卫
- (3)写错误中间件
2.中间件类型
- (1)应用级中间件
- (2)路由器级中间件
- (3)错误处理中间件
- (4)内置中间件
- (5)第三方中间件
二、应用级中间件
- 也就是路由的全局守卫。
- 使用和函数将应用程序级中间件绑定到app对象的实例。
const express=require("express");
const app=express();
app.use((req,res,next)=>{
console.log("应用中间件");
next();
});
app.get('/',(req,res)=>{
res.send("首页");
});
app.get('/login',(req,res)=>{
res.send("登录");
});
app.listen(80,'localhost',()=>{
console.log("http:localhost:80");
})
app.use('/login',(req,res,next)=>{
console.log("login中间件");
next();
})
三、路由级中间件
- 也就是路由模块化。
- 路由中间件与应用级中间件的工作方式相同,只不过它绑定到的实例express.Router()。
1.当一级路由使用
const router=express.Router();
router.get('/',(req,res)=>{
res.send("首页")
})
app.use(router);
2.当二级路由使用
const router=express.Router();
router.get('/',(req,res)=>{
res.send("msg里面的首页");
});
router.get('/login',(req,res)=>{
res.send("login");
});
app.use('/msg',router);
3.抽成外部文件使用
const routes=require("./router/routes");
app.use(routes);
const express=require('express');
const router=express.Router();
router.use((req,res,next)=>{
next();
});
router.get("/",(req,res)=>{
res.send("首页");
});
module.exports=router;
四、错误级中间件
- 错误处理中间件始终采用四个参数。您必须提供四个参数以将其标识为错误处理中间件函数。即使不需要使用该next对象,也必须指定它以维护签名。否则,该next对象将被解释为常规中间件,并且将无法处理错误。
- 以与其他中间件函数相同的方式定义错误处理中间件函数,除了使用四个参数而不是三个参数外,特别是使用参数(err, req, res, next))
- app.js
const fs=require("fs");
app.use((err,req,res,next)=>{
console.log(err.stack);
fs.appendFile('./error/error.txt',err.stack+"\n",(err)=>{
if(err)
next(err);
else
res.status(500).send("服务器响应失败");
});
});
router.get('/downfile',(req,res,next)=>{
let path="./file/abc.docx";
res.download(path,(err)=>{
if(err)
next(err);
console.log("下载成功!");
});
})
五、内置中间件
1.express.static
- 提供静态资产,例如 HTML 文件、图像等。
- app.js
const express=require("express");
const app=express();
let router=require("./router/routes");
let port=8080;
let host='localhost';
app.use(express.static('public'));
app.use('/public',express.static('static'));
app.use(router);
app.listen(port,host,()=>{
console.log(`http://${host}:${port}`);
})
const express=require("express");
const router=express.Router();
router.get('/',(req,res)=>{
res.send("首页");
});
module.exports=router;
2.express.json
const express=require("express");
const app=express();
const ejs=require("ejs");
app.use('/public',express.static('static'));
app.use(express.json());
app.get("/form",(req,res)=>{
ejs.renderFile('views/Form.ejs',(err,html)=>{
if(err)
throw err;
res.send(html);
});
});
app.post('/sendPost',(req,res)=>{
console.log(req.body);
res.send('ok');
})
app.listen(3000,()=>{
console.log('running...');
})
router.get("/form",(req,res)=>{
ejs.renderFile('views/Form.ejs',(err,html)=>{
if(err)
throw err;
res.send(html);
})
})
router.post('/getUser',(req,res)=>{
console.log(req.body);
res.json({msg:'OK',result:{}})
});
router.post('/sendPost',(req,res)=>{
console.log(req.body);
res.send("提交成功!")
})
<form action="/sendPost" method="POST">
<ul>
<li>姓名: <input type="text" name="username"></li>
<li>密码: <input type="text" name="userpwd"></li>
<li><button>登录</button></li>
</ul>
</form>
<button id="btn">请求</button>
<script src="/public/js/jquery-1.9.1.js"></script>
<script>
$(function(){
$("#btn").click(function(){
$.ajax({
method:'post',
data:JSON.stringify({"key":123}),
url:'http://localhost:3000/sendPost',
headers:{
"Content-Type":"application/json"
},
success:function(res){
console.log(res);
}
});
});
});
</script>
- 注:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置,
- 通过express.json()这个中间件,解析表单中的JSON格式的数据
- express.json()方法等价于body-parser
- post请求数据,解析json
- 前端使用ajax请求,需要设置请求头
headers:{
"Content-Type":"application/json"
}
- ajax上的数据不能写成obj,要写成json的字符串格式
- 在服务器,可以使用 req.body 这个属性,来接收客户端发送过来的请求体数据
- 默认情况下,如果不配置解析表单数据中间件,则 req.body 默认等于 undefined
- 除了使用JSON.stringify,还可以使用qs.stringify() 这个方法
export function getVerifyCode(telephone) {
return request({
url: '/......',
method: 'post',
data: qs.stringify({
PhoneNumber: telephone,
}),
});
}
3.express.urlencoded
app.use(express.urlencoded({ extended: false }))
六、第三方中间件
1.cookie-parser写入缓存中间件
- 安装:cnpm install --save-dev cookie-parser
- app.js
const express=require("express");
const ejs=require("ejs");
const app=express();
const cookieParser=require("cookie-parser");
app.use(cookieParser('asdf'));
app.use('/public',express.static(__dirname+"/static"));
app.engine(".html",ejs.__express);
app.set('view engine','html');
app.set("views",__dirname+"/view");
let port=8080;
let host="localhost";
let router=require('./router/routes');
app.use((req,res,next)=>{
next();
})
app.use(router);
app.use((err,req,res,next)=>{
console.log(err.stack);
res.status(500).send("报错");
});
app.listen(port,host,()=>{
console.log(`http://${host}:${port}`);
})
const express=require("express");
const router=express.Router();
const ejs=require("ejs");
router.get("/",(req,res)=>{
ejs.renderFile("view/index.html",{list:[1,2,3]},(err,html)=>{
if(err)
throw err;
res.send(html);
});
});
router.get("/sendData",(req,res)=>{
let query=req.query;
console.log(query);
let str=JSON.stringify(query);
res.cookie('_user',str,{
maxAge:1000*60*60*24*2,
path:'/',
signed:true
});
res.send("写入缓存");
});
router.get("/getcookie",(req,res)=>{
res.send(req.signedCookies['_user']);
})
module.exports=router;
2.multer文件上传中间件
- 安装:cnpm install --save-dev multer
- routes.js
const multer=require("multer");
let storage=multer.diskStorage({
destination(req,file,callback){
callback(null,'./upload');
},
filename(req,file,callback){
callback(null,file.originalname);
}
});
let upload=multer({storage:storage});
router.get("/uploadFile",(req,res)=>{
ejs.renderFile("view/upload.html",(err,html)=>{
if(err)
throw err;
res.send(html);
});
});
router.post("/profile",upload.array("avatar",8),(req,res)=>{
console.log(req.file,req.files);
res.send("上传成功")
})
<form action="/profile" method="POST" enctype="multipart/form-data">
<input type="file" multiple name="avatar">
<button>上传</button>
</form>