我想用响应信息记录每个请求。
我尝试使用中间件,但遇到了问题。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
的 Controller 中, 返回 response.json()
函数代替 response.send()
.如果需要任何其他解释,请告诉我。
关于node.js - 如何在中间件中获取响应体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57551635/