目录
express
Express是一个流行的Node.js Web应用程序框架,用于构建灵活且可扩展的Web应用程序和API。它是基于Node.js的HTTP模块而创建的,简化了处理HTTP请求、响应和中间件的过程。
他的优势:
- 简洁而灵活:Express提供了简单而直观的API,使得构建Web应用程序变得简单快捷。它提供了一组灵活的路由和中间件机制,使开发人员可以根据需求定制和组织应用程序的行为。
- 路由和中间件:Express使用路由和中间件来处理HTTP请求和响应。开发人员可以定义路由规则,将特定的URL路径映射到相应的处理函数。同时,中间件允许开发人员在请求到达路由处理函数之前或之后执行逻辑,例如身份验证、日志记录和错误处理。
- 路由模块化:Express支持将路由模块化,使得应用程序可以根据不同的功能或模块进行分组。这样可以提高代码的组织性和可维护性,使得多人协作开发更加便捷。
基本使用
安装:
npm i express
启动一个http服务,并且响应get和post请求
案例:
import express from 'express';
const app = express()
app.get("/get",(req,res)=> {
res.send("hello world")
})
app.post("/login",(req,res)=> {
res.send("login success")
})
app.listen(3000,()=> {
console.log('server is running on port 3000')
})
接受前端参数:
post请求:req.body 还需要在中间件注册
不同的格式有不同的操作,详情见:node.js依赖express解析post请求四种数据格式() - 王汉炎 - 博客园 (cnblogs.com)
get请求:req.query
动态参数:req.params
案例:
import express from 'express';
import bodyParser from "body-parser"
const app = express()
app.use(bodyParser.urlencoded({
extended: true
}))
app.get("/get",(req,res)=> {
console.log(req.query)
res.send("hello world")
})
app.post("/login",(req,res)=> {
console.log(req.body)
res.send("login success")
})
app.get("/getPage/:id",(req,res) => {
console.log(req.params)
res.send(`this is page ${req.params.id}`)
})
app.listen(3000,()=> {
console.log('server is running on port 3000')
})
执行结果:
模块化
我们正常开发的时候肯定不会把代码写到一个模块里面,Express允许将路由处理程序拆分为多个模块,每个模块负责处理特定的路由。通过将路由处理程序拆分为模块,可以使代码逻辑更清晰,易于维护和扩展
案例:在src下有两个模块,把他们正常使用
src/user
import express from "express";
const router = express.Router()
router.post("/login",(req,res)=> {
res.send({
code: 200,
message: "success",
data: {
token: "1234567890"
}
})
})
router.get("/home",(req,res) => {
res.send({
code: 200,
message: "success",
data: [
{
id: 1,
name: "user1",
age: 20
}
]
})
})
export default router
src/list
import express from "express";
const router = express.Router()
router.get("/getAll",(req,res) => {
res.send({
code: 200,
message: "success",
data: [
{
name: "jjs",
age: 10
}
]
})
})
export default router
index
import express from 'express';
import bodyParser from "body-parser"
import User from "./src/user.js";
import List from "./src/list.js";
const app = express()
app.use(bodyParser.urlencoded({
extended: true
}))
app.use("/user",User)
app.use("/list",List)
app.listen(3000,()=> {
console.log('server is running on port 3000')
})
执行结果:
中间件
中间件是一个关键概念。中间件是处理HTTP请求和响应的函数,它位于请求和最终路由处理函数之间,可以对请求和响应进行修改、执行额外的逻辑或者执行其他任务。
中间件函数接收三个参数:req
(请求对象)、res
(响应对象)和next
(下一个中间件函数)。通过调用next()
方法,中间件可以将控制权传递给下一个中间件函数。如果中间件不调用next()
方法,请求将被中止,不会继续传递给下一个中间件或路由处理函数
案例: 实现一个日志中间件
需要使用的技术:
log4js是一个用于Node.js应用程序的流行的日志记录库,它提供了灵活且可配置的日志记录功能。log4js允许你在应用程序中记录不同级别的日志消息,并可以将日志消息输出到多个目标,如控制台、文件、数据库等
安装:
npm i log4js
import log4js from 'log4js';
// 配置log4js 输出到控制台和写入到logs/server.log文件中
log4js.configure({
appenders:{
out: {
type: 'stdout',
layout: {
type: "colored"
}
},
file: {
type: 'file',
filename: 'logs/server.log', // 日志文件名
}
},
categories:{
default: {
appenders: ['out', 'file'],
level: 'debug' // 日志级别
}
}
})
const logger = log4js.getLogger("default");
// 日志中间件
export default function (req, res, next) {
logger.debug(`[${req.method}] ${req.url}`);
next();
}
index.js
import express from 'express';
import bodyParser from "body-parser"
import User from "./src/user.js";
import List from "./src/list.js";
import loggerMiddleware from "./middleware/logger.js"
const app = express()
app.use(loggerMiddleware)
app.use(bodyParser.urlencoded({
extended: true
}))
app.use("/user",User)
app.use("/list",List)
app.listen(3000,()=> {
console.log('server is running on port 3000')
})
执行效果:
防盗链
在网页或其他网络资源中,通过直接链接到其他网站上的图片、视频或其他媒体文件,从而显示在自己的网页上。这种行为通常会给被链接的网站带来额外的带宽消耗和资源浪费,而且可能侵犯了原始网站的版权。
通过 防盗链(Hotlinking) 来解决
为了防止盗链,网站管理员可以采取一些措施:
- 使用水印技术:在图片或视频上添加水印可以帮助识别盗链行为,并提醒用户资源的来源。
- 使用Referrer检查:网站可以检查HTTP请求中的Referrer字段,该字段指示了请求资源的来源页面。如果Referrer字段不符合预期,就拒绝提供资源。这种方法可以在服务器配置文件或脚本中实现。
接下来将会以referrer来写一个防盗链的案例
- 第一步需要初始化静态资源目录
express.static
express动静分离非常的便捷,只需要use以下即可
import express from 'express';
import bodyParser from "body-parser"
import loggerMiddleware from "./middleware/logger.js"
const app = express()
// 静态资源
app.use(express.static('static'))
app.use("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*")
next()
})
app.use(loggerMiddleware)
app.use(bodyParser.urlencoded({
extended: true
}))
app.listen(3000,()=> {
console.log('server is running on port 3000')
})
添加防盗链
// 防止热链中间件
function preventHotlink(req,res,next) {
const referer = req.get('Referer')
if(referer) {
const {hostname,port} = new URL(referer)
if(hostname !== 'localhost') {
res.status(403).send('禁止访问')
return
}
}
next()
}
app.use(preventHotlink)
效果图:
响应头
HTTP响应头(HTTP response headers)是在HTTP响应中发送的元数据信息,用于描述响应的特性、内容和行为。它们以键值对的形式出现,每个键值对由一个标头字段(header field)和一个相应的值组成。
响应头和跨域的关系
跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种机制,用于在浏览器中实现跨域请求访问资源的权限控制。当一个网页通过 XMLHttpRequest 或 Fetch API 发起跨域请求时,浏览器会根据同源策略(Same-Origin Policy)进行限制。同源策略要求请求的源(协议、域名和端口)必须与资源的源相同,否则请求会被浏览器拒绝
端口和协议不一样就会报错,需要配置响应头,
app.use("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*")
next()
})
还可以指定路径访问
app.use('*',(req,res,next)=>{
res.setHeader('Access-Control-Allow-Origin','http://localhost:5500') //允许localhost 5500 访问
next()
})
自定义响应头
后端可以设置响应头并且抛出,前端即可使用
app.get('/getAll', (req, res) => {
res.set('count', '1')
res.setHeader('Access-Control-Expose-Headers', 'count')
res.json({
code: 200
})
})
前端读取:
const headers = res.headers
console.log(headers.get('count')) //读取自定义响应头
请求头
默认情况下cors仅支持客户端向服务器发送如下九个请求头
- Accept:指定客户端能够处理的内容类型。
- Accept-Language:指定客户端偏好的自然语言。
- Content-Language:指定请求或响应实体的自然语言。
- Content-Type:指定请求或响应实体的媒体类型。
- DNT (Do Not Track):指示客户端不希望被跟踪。
- Origin:指示请求的源(协议、域名和端口)。
- User-Agent:包含发起请求的用户代理的信息。
- Referer:指示当前请求的源 URL。
Content-type: application/x-www-form-urlencoded | multipart/form-data | text/plain
我们服务端默认只支持 GET POST HEAD OPTIONS 请求
例如我们遵循restFui 要支持PATCH
或者其他请求
就需要设置如下内容:
req.set('Access-Control-Allow-Methods','POST,GET,OPTIONS,DELETE,PATCH')