node http-proxy:请求体的异步修改

时间:2017-05-15 11:27:15

标签: node.js node-http-proxy

我需要异步修改请求体。有点像这样:

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中删除各种监听器但没有成功..

3 个答案:

答案 0 :(得分:2)

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

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

此lib上的最小分支可以是:

// 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,你可以对事件和回调进行全面控制。

答案 1 :(得分:1)

您可以在selfHandleResponse: true内设置HttpProxy.createProxyServer。然后,这将允许(并强迫)您手动处理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
});

答案 2 :(得分:0)

我来这里是寻找一个稍微不同的问题的解决方案:在代理之前修改请求 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);