【问题标题】:How to return to client in onProxyReq of http-proxy-middleware如何在 http-proxy-middleware 的 onProxyReq 中返回客户端
【发布时间】:2021-08-11 13:23:15
【问题描述】:

我正在尝试使用 express 和 http-proxy-middleware@2.0.1 创建一个带有一些内置验证的反向代理。希望在 onProxyReq 函数中,我可以进行检查,如果失败,我会将错误返回给调用者,而不是继续代理请求。

似乎如果我立即发送带有“无效”的 404,那么它会按预期工作。如果在执行验证操作时有任何延迟(这里用 setTimeout() 模拟),那么它会抛出错误“在将标头发送到客户端后无法设置标头”。有没有办法让 onProxyReq “等待”直到我的验证完成,我可以决定是否需要以错误响应客户端,或者继续使用代理。

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

function onProxyReq(proxyReq, req, res) {
    // Some validation

    // ** This causes the error "Cannot set headers after they are sent to the client"
    // setTimeout(()=>{
    //     res.status(404).send('Invalid')
    // }, 500)
    
    // ** This returns "Invalid" to the client as expected
    return res.status(404).send('Invalid')
}

// proxy middleware options
const options = {
  target: 'https://google.com',
  changeOrigin: true,
  logLevel: 'debug',
  onProxyReq,
};

const testProxy = createProxyMiddleware(options);
const app = express();

app.use('/', testProxy);


app.listen(3000);

【问题讨论】:

    标签: node.js http-proxy-middleware


    【解决方案1】:

    我也面临着类似的情况。我已经阅读了 node-proxy npm 模块(由 http-proxy-middleware 使用)中的代码。引发 proxyReq 事件的相关行是 here。无法在 onProxyReq 事件中取消或推迟代理请求。

    对我来说,解决方案在于在代理中间件之前插入我自己的中间件。调整您的示例代码以遵循此模式将导致如下所示:

    const express = require('express');
    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    function customValidation(req, res, next) {
        setTimeout(()=>{
            if (validationSucceeds) {
                 next(); //forward request through to proxy middleware
            } else {
                 res.status(404).send('Invalid');
            }
        }, 500)
    };
    
    // proxy middleware options
    const options = {
      target: 'https://google.com',
      changeOrigin: true,
      logLevel: 'debug'
    };
    
    const testProxy = createProxyMiddleware(options);
    const app = express();
    
    app.use('/', [customValidation, testProxy]);
    
    app.listen(3000);
    

    【讨论】:

    • 我实际上最终用我自己的中间件来做检查并在 req 对象上设置一个布尔值,然后在 onProxyReq 函数内部如果布尔值是假的,我做一个 res.status( 404).send('error msg') 调用,它似乎工作。
    • 很好,你的方法非常相似。与我上面的唯一区别是,如果验证不成功,则根本不会调用代理中间件。
    • @MarkGlasgow 我想在发送到我的代理服务器之前访问我的req.body,我尝试了你的方法。但在我的中间件内部req.body 是未定义的。你能建议我为什么以及我还能做些什么来实现我想要的吗?谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-05-23
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 2020-03-26
    相关资源
    最近更新 更多