nodejs常用场景
日志记录
-
实现思路:
-
在express中,使用
log4js
,配置一个用于接口请求的日志分类,如:const path = require('path'); const log4js = require('log4js'); log4js.configure({ // 配置输出出口 appenders: { // 默认出口 default: { type: 'stdout' // 输出出口类型,stdout表示控制台输出 }, api: { // type: 'file', // 输出出口类型 type: 'dateFile', // 输出出口类型为文件,并且文件名带有日期 keepFileExt: true, // 保持日志输出文件为log文件类型 daysToKeep: 10, // 保存10天内的日志,默认为0表示都保存 filename: path.resolve(__dirname, '../', 'logs', 'api', 'logging.log'), // 文件路径、文件名 maxLogSize: 1024 * 1024 * 5, // 输出日志文件的最大字节数(1024字节=1kb),超出大小后会自动生成日志备份文件 layout: { type: 'pattern', // pattern: 表示自定义格式 // %c: 日志分类名称 // %d: 时间 // %p: 日志级别 // &m: 日志内容 // %n: 换行 pattern: '%c [%d{yyyy/MM/dd hh.mm.ss}] [%p]: %m%n' // 定义格式 } // 日志输出格式 } }, // 配置分类 categories: { // api为分类名称,名称可以随意取 api: { appenders: ['api'], // 表示该分类使用出口为api的配置进行日志写入 level: 'off' // 日志记录级别 }, // 必须配置默认分类 default: { appenders: ['default'], // 表示该分类使用出口为default的配置进行日志写入 level: 'info' // 日志记录级别 } } }); process.on('exit', () => { // 程序退出时,将日志完成记录 log4js.shutdown(); }); // sqlLogger.debug("日志内容"); // 使用配置好的日志分类sql exports.apiLogger = log4js.getLogger('api');
-
配置一个express中间件,当接口请求时,通过引入日志分类进行日志输出
const { sqlLogger } = require('日志配置文件路径') module.exports = (req, res, next) => { // 输出日志 sqlLogger.debug(req.url); next() }
-
-
实现方式:可以使用
log4js
提供的api(connectLogger
)进行日志配置,该api会根据传入的配置返回一个express中间件- 文档地址:log4js-node by log4js-node
log4js
的connectLogger
方法中可用的格式占位符及其含义:remote-addr
:客户端的IP地址:method
:请求方法,如GET
、POST
等:url
:请求的URL路径:http-version
:请求的HTTP版本,如HTTP/1.1
:status
:服务器返回的HTTP状态码:res[content-length]
:响应的Content-Length
头的值,表示发送给客户端的字节数:referrer
或:referer
:请求的Referer
头的值,即用户是从哪个页面链接过来的:user-agent
:请求的User-Agent
头的值,表明发出请求的浏览器或其他客户端类型:response-time
:从接收到请求到发送响应的时间(以毫秒为单位)
文件上传
-
上传文件通常是通过
HTTP
协议的multipart/form-data
编码类型来实现的 -
上传文件过程:
-
前端:
-
使用
HTML
的<form>
元素,并设置enctype
属性为multipart/form-data
,这样表单提交的内容就可以包含文件数据,并且使用<input type="file">
标签允许用户选择文件 -
当用户提交表单时,浏览器会构造一个
multipart/form-data
类型的HTTP
请求;这个请求的body部分被分成多个部分(part),每个部分对应一个表单字段,如下:
-
-
node.js服务端:使用express的一个**中间件
multer
**来处理文件上传
-
文件下载
-
原理:通过设置 HTTP 响应头,指示浏览器以下载的形式处理响应内容
-
实现方式:通过
express
回调函数中的response
响应参数-
手动设置 HTTP 响应头,主要是以下3个字段
-
Content-Disposition
:attachment; filename="文件名称.文件类型后缀"
- 告诉浏览器这是一个附件,应该提示用户下载,而不是直接在浏览器中打开
-
Content-Type
:根据文件类型自动推断- 设置为
application/octet-stream
:将文件以数据流的形式响应给浏览器
- 设置为
-
Content-Length
:文件的字节数const express = require('express'); const fs = require('fs'); const router = express.Router(); router.get('/download', (req, res) => { const filePath = '本地文件路径'; const fileName = '文件名称'; const stat = fs.statSync(filePath); // 设置响应头 res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`); // 以数据流的形式响应 res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Length', stat.size); // 创建可读流 const readStream = fs.createReadStream(filePath); // 管道操作:可读流连接到可写流(res响应) readStream.pipe(res); });
-
-
使用
res.download()
:自动设置适当的 HTTP 响应头,并将文件发送给客户端
-
图片处理
- 使用第三方库:
sharp
- 中文文档:sharp 中文网 (nodejs.cn)
图片防盗链
- 使用场景:用于防止他人未经授权在自己的网站上展示你的图片资源
- 实现思路:
- 检查 Referer 头部:
- 当浏览器请求一个图片资源时,通常会发送一个 HTTP 请求头,其中包含一个
Referer
字段。这个字段表明了发起请求的页面的 URL - 服务器可以检查这个
Referer
字段,如果它不是来自允许的域名,服务器可以选择拒绝这个请求
- 当浏览器请求一个图片资源时,通常会发送一个 HTTP 请求头,其中包含一个
- 使用 Token 验证:
- 可以在图片 URL 中加入一个有效的 token,只有当 token 验证通过时,才允许加载图片
- 检查 Referer 头部:
- 实现方法:通过添加一个中间件
代理(重点场景)
-
代理使用的场景:如vue2中配置文件
vue.config.js
和vite.config.ts
中的proxy
代理配置 -
node.js中可以使用
http
模块可以通过中间件的形式创建一个简单的代理服务器const http = require('http'); module.exports = (err, req, res, next) => { const options = { hostname: 'target-server.com', port: 80, path: req.url, method: req.method, headers: req.headers }; const proxyReq = http.request(options, (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); // 把目标服务器的响应体通过管道pipe传输给本地node.js代理服务器响应体 proxyRes.pipe(res, { end: true }); }); // 把请求体通过管道pipe写入给本地node.js代理服务器 req.pipe(proxyReq); }
-
使用第三方库(推荐):
http-proxy-middleware
生成验证码
- 实现方式一:通过canvas绘制完成后通过 HTTP 响应返回
- 实现方式二:第三方库,如
svg-captcha