node.js - 如何在中间件中获取响应体?

标签 node.js express

我想用响应信息记录每个请求。

我尝试使用中间件,但遇到了问题。
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/

相关文章:

javascript - 如何编写多线路径进行路由?

macos - 通过 Express 和 MongoDB 使用 session ,为什么我只能连接一次路由,除非我更改 session key ?

用于快速路由器 url 的正则表达式以匹配以/public/开头的路径

html - 在 node.js Express 4 中发布带有图像、css 和 javascript 的 html

javascript - s.replace 不是sequelize.fn 'AVG' 上的函数

javascript - Node.js 通过回调返回多个错误的约定?

javascript - 异步/等待返回 Promise { <pending> }

javascript - 如何将所有这些逻辑与 javascript Promises 混合在一起?

javascript - Electron 生成器目标 : mac vs. mas

javascript - Handlebars Helper 比较值(如果 v1 === v2),并渲染上层范围?