在路由相应之前就会执行中间件的内容,例如在中间件中进行赋值,这种就可以在路由执行时使用这个值。
所以中间件就是服务器开启之后和路由响应之前执行的一个函数。这个函数可以操作req与res。使用next()向下传递到下一个中间件,最后传到路由。
例如开启三个中间件的写法:
app.use((req, res, next) => { console.log("中间件1"); req.requestTime = Date.now(); next(); }); app.use((req, res, next) => { console.log("中间件2"); next(); }); app.get("/", (req, res) => { console.log(Date.now() - req.requestTime); res.send("Hello World!"); });浏览器使用ajax时,如果请求的接口地址和当前打开的页面地址不同源称之为跨域。
协议和地址、端口都一样成为同源。有一个不同则为不同源。
同源与不同源的意义
浏览器安全策略。
只需要在响应头处设置Access-Control-Allow-Origin为*即可。
app.post("/login", (req, res) => { // 设置响应头,允许资源被访问、共享 res.setHeader("Access-Control-Allow-Origin", "*"); // 接收用户传递过来的用户名和密码 let { username, password } = req.body; if (username == "admin" && password == "123") { res.send({ code: 200, msg: "登陆成功", }); } else { res.send({ code: 400, msg: "登陆失败", }); } });自己写中间件
因为中间件会在执行路由之前会被调用,因此可以将设置响应头在中间件中设置。
app.use((req, res, next) => { // 设置响应头,允许资源被访问、共享 res.setHeader("Access-Control-Allow-Origin", "*"); next(); });使用第三方模块
安装cors模块(npm i cors)。接下来使用即可。
const cors = require("cors"); app.use(cors());原理
通过动态创建script标签,通过script标签的src请求没有域限制来获取资源
例如在html页面中,将script标签地址改为后端接口。
app.get("/all", (req, res) => { console.log(Date.now() - req.requestTime); res.send("console.log('hah')"); }); <script src="http://127.0.0.1:3000/all"></script>那么当服务器开启时,我们就会看到返回来的内容会当作JavaScript代码执行。
因此此方式需要与前端进行配合才可使用。例如前端通过get参数方式将函数名传递给后端。
<script> function fn() { console.log('这是事先准备好的函数!') } function fn1(backData) { console.log(backData) } </script> <script src="http://127.0.0.1:3000/all?callback=fn"></script> app.get("/all", (req, res) => { let fn = req.query.callback; res.send(`fn()`); }); app.get("/all", (req, res) => { let fn = req.query.callback; res.send(`${fn}({'name':'haha','price':100})`); });动态获取数据的示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button id="btn">点我获取</button> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> function sb(backData) { // 接收后端的数据 console.log(backData); } $('#btn').on('click', function () { // 1. 动态创建script标签 var script1 = document.createElement('script') $(script1).attr('src', 'http://127.0.0.1:3000/all?callback=sb') // 2. 把script添加到body中使用 $('body').append(script1) }) </script> </body> </html> app.get("/all", (req, res) => { let fn = req.query.callback; res.send(`${fn}({'name':'haha','price':100})`); });如果访问的接口支持jsonp,那么jQuery会自动创建script标签
