【问题标题】:node http-proxy: async modification of request bodynode http-proxy:异步修改请求体
【发布时间】:2017-05-15 11:27:15
【问题描述】:

我需要异步修改请求正文。类似这样的东西:

proxy.on('proxyReq', function(proxyReq, req, res, options) {
  if(req.body) {
    new Promise(function(resolve){ 
      setTimeout(function() { // wait for the db to return
        'use strict';
        req.body.text += 'test';
        let bodyData = JSON.stringify(req.body);
        proxyReq.setHeader('Content-Type','application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        // stream the content
        proxyReq.write(bodyData);
        resolve();
      },1);
    });
  }
});

当我运行它时,我收到错误消息,说一旦设置了标头就无法修改标头。这是有道理的。

在我准备好之前如何停止发送请求?我已经看过从 proxyReq 中删除各种侦听器但没有成功..

【问题讨论】:

标签: node.js node-http-proxy


【解决方案1】:

通过查看source code @-) 似乎不太可能,因为发送了proxyReq 事件,然后代码继续运行。

如果它改为等待一个承诺,这是可能的(如果你也返回那个承诺)。

这个库的最小分支可以是例如:

// Enable developers to modify the proxyReq before headers are sent
proxyReq.on('socket', function(socket) {
  if(server) { server.emit('proxyReq', proxyReq, req, res, options); }
});

(proxyReq.proxyWait || Promise.resolve())
    .then( ... // rest of the code inside the callback 

然后

proxy.on('proxyReq', function(proxyReq, req, res, options) {
  if(req.body) {
    proxyReq.proxyWait = new Promise(function(resolve){ 
      setTimeout(function() { ...

但根据您的用例,可能还有其他解决方案。例如,考虑是否真的有必要使用这个代理库。它你也可以直接使用 http,你可以控制所有的事件和回调。

【讨论】:

  • 我已经在源代码中挖掘了一段时间 :) 我认为你的建议不会奏效,因为我理解 server.emit('proxyReq'.. 本身就是异步的。所以代码第一次通过时不会出现proxyWait (proxyReq.proxyWait || Promise.resolve())..
  • hmm,发射与 nodejs 发射不同/相似吗,which is synchronous - 替代 proxyWait 方法,您可以使用自己的回调从回调中发射,以便在准备好时进行通信(e ..g new Promise(...).then(proxyReq.emit('doneProxy')) 然后你在原始源代码中等待这个事件,但这意味着你必须在proxyReq 事件的实际发出之前注册一个proxyReq.on('doneProxy', () => // rest of the code),如果这有意义的话 - 我很漂亮确定这不是最好的主意:P
【解决方案2】:

您可以在HttpProxy.createProxyServer 中设置selfHandleResponse: true。然后,这允许(并强制)您手动处理 proxyRes

const proxy = HttpProxy.createProxyServer({selfHandleResponse: true});
proxy.on('proxyRes', async (proxyReq, req, res, options) => {
  if (proxyReq.statusCode === 404) {
    req.logger.debug('Proxy Request Returned 404');
    const something = await doSomething(proxyReq);
    return res.json(something);
  }
  return x;// return original proxy response
});

【讨论】:

    【解决方案3】:

    我来这里是为了寻找稍微不同的问题的解决方案:在代理之前修改请求headers(不是正文)。

    我在这里发布它以防它对其他人有帮助。也许代码也可以修改请求正文。

    const http = require('http');
    const httpProxy = require('http-proxy');
    
    var proxy = httpProxy.createProxyServer({});
    
    var server = http.createServer(function(req, res) {
        console.log(`${req.url} - sleeping 1s...`);
        setTimeout(() => {
            console.log(`${req.url} - processing request`);
            req.headers['x-example-req-async'] = '456';
            proxy.web(req, res, {
                target: 'http://127.0.0.1:80'
            });
        }, 1000);
    });
    
    server.listen(5050);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      相关资源
      最近更新 更多