Node.js Express如何获取解析前的原始HTTP请求报文?
Express获取原始HTTP请求报文的实现方案
1. 获取原始请求行+请求头
Express封装的req对象继承自Node.js原生http.IncomingMessage,可以直接通过内置属性拼接出和原始报文完全一致的请求头部分:
app.use((req, res, next) => { // 拼接请求行:方法 路径 HTTP版本 const requestLine = `${req.method} ${req.url} HTTP/${req.httpVersion}`; // 拼接请求头:用rawHeaders保留原始大小写、顺序 let headerStr = ''; for (let i = 0; i < req.rawHeaders.length; i += 2) { headerStr += `${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`; } // 完整的原始请求头报文,输出格式和你给出的示例完全一致 const rawRequestHeader = `${requestLine}\r\n${headerStr}`; console.log(rawRequestHeader); next(); });
注意:不要用
req.headers拼接,Express会自动把请求头的键转为小写,丢失原始格式,req.rawHeaders是客户端发送的原始扁平数组,顺序、大小写都和原始报文一致。
2. 获取未解析的原始请求体
如果需要获取POST/PUT等请求的原始请求体,不要在express.json/express.urlencoded这类解析中间件之后处理,推荐直接用解析中间件内置的verify配置项捕获原始内容:
// 解析JSON请求体同时保存原始内容 app.use(express.json({ verify: (req, res, buffer) => { // buffer为原始请求体的Buffer格式,转字符串直接调用toString() req.rawBody = buffer.toString(); } })); // 解析表单请求体同时保存原始内容 app.use(express.urlencoded({ extended: true, verify: (req, res, buffer) => { req.rawBody = buffer.toString(); } }));
如果没有用内置解析中间件,也可以手动监听数据流获取:
app.use((req, res, next) => { const chunks = []; req.on('data', chunk => chunks.push(chunk)); req.on('end', () => { req.rawBody = Buffer.concat(chunks).toString(); next(); }); });
注意事项
- 大请求体/大文件上传场景不建议直接缓存全部原始内容,会占用过多内存,可按需流式处理
- 拼接完整原始报文时,请求头和请求体之间需要空一行,格式为
${rawRequestHeader}\r\n${rawBody}
内容的提问来源于stack exchange,提问作者Jacob FW
相关产品推荐
相关产品推荐

