Express框架---中间件

一、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.抽成外部文件使用

  • app.js
const routes=require("./router/routes");
app.use(routes);
  • routes.js
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
// 错误中间件
// 地址http://localhost/downfile
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("服务器响应失败");
   });
});
  • routes.js
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}`);
})
  • routes.js
const express=require("express");
const router=express.Router();
// 路由配置
router.get('/',(req,res)=>{
   res.send("首页");
});
module.exports=router;

2.express.json

  • 使用 JSON 负载解析传入请求。
  • app.js
const express=require("express");
const app=express();
const ejs=require("ejs");
app.use('/public',express.static('static'));
// 注:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置,
// 通过express.json()这个中间件,解析表单中的JSON格式的数据
// express.json()方法等价于body-parser
// post请求数据,解析json
// 前端使用ajax请求,需要设置请求头
/**
headers:{
    "Content-Type":"application/json"
}
ajax上的数据不能写成obj,要写成json的字符串格式
*/
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)=>{
   // 在服务器,可以使用 req.body 这个属性,来接收客户端发送过来的请求体数据
   // 默认情况下,如果不配置解析表单数据中间件,则 req.body 默认等于 undefined
   console.log(req.body);
   res.send('ok');
})
app.listen(3000,()=>{
   console.log('running...');
})
  • routes.js
router.get("/form",(req,res)=>{
   ejs.renderFile('views/Form.ejs',(err,html)=>{
       if(err)
           throw err;
       res.send(html);
   })
})
// post请求
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.ejs
	<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

  • 使用 URL 编码的有效负载解析传入请求。
//下面这个内置中间件  解析表单上的数据的
app.use(express.urlencoded({ extended: false }))

六、第三方中间件

1.cookie-parser写入缓存中间件

  • 安装:cnpm install --save-dev cookie-parser
  • app.js
// 使用ejs模板
const express=require("express");
const ejs=require("ejs");
const app=express();
// 引入cookie-parser
const cookieParser=require("cookie-parser");
app.use(cookieParser('asdf'));
// 设置静态资源目录
app.use('/public',express.static(__dirname+"/static"));
// 设置express框架使用ejs模板引擎
// 修改ejs模板后缀为html
app.engine(".html",ejs.__express);
// 设置views文件为模板引擎的目录
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)=>{
   // 设置响应头
   // res.setHeader();
   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}`);
})
  • routes.js
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);
   //console.log(str);
   res.cookie('_user',str,{
       maxAge:1000*60*60*24*2,
       path:'/',
       signed:true
   });
   res.send("写入缓存");
});
router.get("/getcookie",(req,res)=>{
   // 未加密使用下面这个读取
   // res.send(req.cookies['_user']);
   // 加密使用下面这个读取
   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.single("avatar"),(req,res)=>{
//     console.log(req.file);
//     res.send("上传成功")
// })

// 多文件上传
router.post("/profile",upload.array("avatar",8),(req,res)=>{
   console.log(req.file,req.files);
   res.send("上传成功")
})
  • upload.html
	<form action="/profile" method="POST" enctype="multipart/form-data">
       <input type="file" multiple name="avatar">
       <button>上传</button>
   </form>
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南初️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值