node.js - 如何在中间件中获取响应体?
问题描述
我想用响应信息记录每个请求。
我尝试使用中间件,但我遇到了问题。
res.body
是未定义的。
app.use((req, res, next) => {
var time = Date.now();
res.on('finish', function() {
var clientIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
var method = req.method;
var path = req.baseUrl;
var duration = Date.now() - time;
console.log({
clientIp,
elapsedTime: `${duration}ms`,
hostname: req.headers.host,
level: 'INFO',
method,
path,
phase: process.env.NODE_ENV,
reqBody: req.body,
reqHeaders: req.headers,
resBody: res.body,
resHeaders: res.getHeaders(),
status: res.statusCode
});
});
next();
});
实际上客户端上有响应数据。
如何在中间件中获取响应正文?
解决方案
响应可以被覆盖response.json
函数拦截。通过这样做,并添加我们的custom function
, 每次response.json()
被调用,我们的拦截函数就会被触发。
中间件/response.filter.js:
// Response Interceptor Middleware
export default (request, response, next) => {
try {
const oldJSON = response.json;
response.json = (data) => {
// For Async call, handle the promise and then set the data to `oldJson`
if (data && data.then != undefined) {
// Resetting json to original to avoid cyclic call.
return data.then((responseData) => {
// Custom logic/code.
response.json = oldJSON;
return oldJSON.call(response, responseData);
}).catch((error) => {
next(error);
});
} else {
// For non-async interceptor functions
// Resetting json to original to avoid cyclic call.
// Custom logic/code.
response.json = oldJSON;
return oldJSON.call(response, finalResponse);
}
}
} catch (error) {
next(error);
}
}
在Server.js
文件中,注册中间件:
// Server.js file
import externalResponseFilter from "./middleware/response.filter.js:";
// Create Express server
const app = express();
// Response interceptor - Initialization.
app.use(externalResponseFilter);
在您返回的控制器中response
,返回response.json()
函数而不是response.send()
.
让我知道是否需要任何其他解释。
推荐阅读
- bash - shell vs 终端 vs 命令行 vs BASH?
- python - fcntl.lockf 在文件的上下文管理器中
- powershell - Powershell foreach 和 export-csv 不起作用
- c - 我如何传递指针参数有什么问题吗?
- android - 任务 ':app:processDebugResources' 执行失败。无法执行 aapt Ionic 4 android
- python - 使用 Notepad++ 时如何删除关联符号?
- swift - CloudRun 中的 Apple SwiftNIO - 这可能吗?
- c++ - 如何编写 C++ 库以使用 span 的任何实现
? - ios - 如何从 MPMediaQuery 中删除重复项?下面的努力有一个致命的错误
- javascript - 用Javascript将JSON对象传递给表,不知所措