常用中间件
- express.static
const express = require('express')
const app = express()
const path = reuire("path")
// 静态资源映射
const staticRoot = path.resolve(__dirname, "../public")
/**
* 当请求时,会根据请求路径(req.path),从指定的目录中寻找是否存在该文件,
* 如果存在,直接响应文件内容,而不再移交给后续的中间件;
* 如果不存在文件,则直接移交给后续的中间件处理;
* 默认情况下,如果映射的结果是一个目录,则会自动使用index.html文件
*/
app.use(express.static(staticRoot))
- express.json()
// 解析HTTP请求中的application/x-www-form-urlencoded格式的数据,
// 并将其转换为JavaScript对象
app.use(express.urlencoded({
extends: true
}))
- express.urlencoded()
// 解析HTTP请求中的json格式的数据,
app.use(express.json())
路由
// 路由统一处理api请求
const studentRouter = express.Router()
studentRouter.get("/", (req, res) => {})
studentRouter.get("/:id", (req, res) => {})
studentRouter.post("/", (req, res) => {})
studentRouter.delete("/:id", (req, res) => {})
app.use("/api/student", studentRouter)
cookie
cookie的组成
- key: 键,比如身份编号
- value:值,它可以是任何信息
- domain:域,表达这个cookie是属于哪个网站;如果不设置,浏览器自动设置为当前的请求域
- path:路径,表达这个cookie是属于该网站的哪个基路径的;如果不设置默认当前请求路径
- secure:是否使用安全传输,设置该值只能是https请求
- expire:过期时间,表示该cookie在什么时候过期;必须是一个有效的GMT时间,比如Fri,17 Apr 2022 09:35:59 GMT
- httponly:设置cookie是否仅用于传输。如果设置了该值,表示cookie仅用于传输,而不允许在客户端通过js获取,这对防止跨站脚本攻击XSS会很有用
响应头按照下面的格式设置:
set-cookie: cookie1
set-cookie: cookie2
…
cookie格式如下:键=值;path=?;domain=?expire=?;secure;httponly
const express = require("express")
const app = express()
/**
* 加入cookie-parser中间件
* 加入后,会在req对象中注入cookies属性,用于获取所有请求传递过来的cookie
* 加入后,会在res对象中注入cookie方法,用于设置cookie
*/
const cookieParser = require("cookie-parser")
app.use(cookieParser)
app.post('/login', (req, res) => {
const result = login(...)
if(result){
const value = result.id
res.cookie("token", value, {
path: '/',
domain: "localhost",
maxAge: 7*24*3600*1000
})
res.header("authorization", value)
}
})
跨域
npm i cors
const express = require('express')
const app = express()
const cors = require("cors")
// 所有接口支持跨域
app.use(cors())
// 针对某一类接口处理跨域
// 可自定义响应头, 配置白名单
const whiteList = ["http://example.com", "http://example2.com"]
const corsOptions = {
/**
* 默认配置
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
*/
origin: function(origin, callback){
if(whiteList.indexOf(origin) !== -1){
callback(null, true)
}else{
callback(new Error("not allowed by cors"))
}
}
}
app.get("/user/:id", cors(corsOptions), (req, res, next) => {})
session
npm i express-session
const express = require('express')
const app = express()
const session = require("express-session")
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: {secure: true}
}))
jwt
** 为多种终端设备,提供统一的、安全的令牌格式 **
jwt只是一个令牌格式而已,你可以把它存储到cookie,也可以存储到localstorage,没有任何限制;由header、payload、signature三部分组成,主体信息在payload;jwt难以被篡改和伪造。这是因为有第三部分的签名存在
同样的,对于传输,你可以使用任何传输方式来传输jwt,一般来说,我们会使用消息头来传输它
set-cookise: token=jwt令牌
authorization: jwt令牌
{ … , token: jwt令牌}
客户端拿到令牌后,当后续请求发生时,你只需要将它作为请求的一部分发送给服务器。
const jwt = require("jsonwebtoken")
const secrect = "secrectKey"
const cookieKey = "token"
// 颁发jwt
exports.publish = function (res, maxAge = 3600*24, info={}){
const token = jwt.sign(info, secrect, {
expiresIn: maxAge
})
// 添加到cookie
res.cookie(cookieKey, token, {
maxAge: maxAge * 1000,
path: "/"
})
// 添加其他传输
res.header("authorization", token)
}
exports.verify = function (req) {
let token;
// 尝试从cookie中获取
token = req.cookies[cookieKey]
if(!token){
// 尝试从header中获取
token = req.header.authorization
if(!token){
return null
}
// authorization: bearer token
token = token.split(" ")
token = token.length === 1 ? token[0] : token[1]
}
try {
const result = jwt.verify(token, secrect)
return result
} catch (error) {
return null
}
}
代理
npm i http-proxy-middleware
const { request } = require("express")
const { createProxyMiddleware } = require("http-proxy-middleware")
const options = {
target: "http://www.example",
changeOrigin: true,
ws: true,
pathRewrite: {'^/old/api' : '/new/api'},
router: {
'integration.localhost:3000' : 'http://127.0.0.1:8001', // host only
'staging.localhost:3000' : 'http://127.0.0.1:8002', // host only
'localhost:3000/api' : 'http://127.0.0.1:8003', // host + path
'/rest' : 'http://127.0.0.1:8004' // path only
}
}
module.exports = createProxyMiddleware(options)
/** 手写代理 */
const http = require("http")
module.exports = (req, res, next) => {
const context = "/data"
if(!req.path.startsWith(context)){
// 不需要代理
next()
return
}
// 需要代理
const path = req.path.substr(context.length)
http.requset({
hots: "",
port: 5100,
path: path,
method: req.method,
headers: req.headers
}, (response) => {
// 代理响应对象
res.status(response.statusCode)
for (const key in response.headers) {
res.setHeader(key, response.headers[key])
}
response.pipe(res)
})
req.pipe(request)
}
express和koa异步区别
在express中 next()返回的是void类型
koa中next()返回的是Promise类型
// koa 洋葱模型
app.use(async(ctx, next) => {
// 可直接使用async await处理异步函数
await next()
})

被折叠的 条评论
为什么被折叠?



