如何在node-http-proxy响应中添加标头

14

我需要解决第三方服务的CORS问题,因此我想建立一个代理来添加头部信息"Access-Control-Allow-Origin: *"。

为什么这段代码没有添加头部信息呢?

httpProxy = require('http-proxy');

var URL = 'https://third_party_server...';

httpProxy.createServer({ secure: false, target: URL }, function (req, res, proxy) {

  res.oldWriteHead = res.writeHead;
  res.writeHead = function(statusCode, headers) {
    /* add logic to change headers here */

    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');

    res.oldWriteHead(statusCode, headers);
  }

  proxy.proxyRequest(req, res, { secure: false, target: URL });

}).listen(8000);

4
请尝试使用cors模块,运行npm install cors安装该模块。该模块可以帮助解决跨域请求问题。 - Ashok Kumar Sahoo
3个回答

18

你可以使用proxyRes事件。

这样的代码应该能够工作:

proxy.on('proxyRes', function(proxyRes, req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
});

完整的工作示例(嗯,当我说完整的时候,我并不是说这是一个安全可靠的真正代理,但它可以完成你的问题):

var http = require('http'),
    httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
var server = http.createServer(function(req, res) {
    proxy.web(req, res, {
        target: 'https://third_party_server...',
        secure: false,
        ws: false,
        prependPath: false,
        ignorePath: false,
    });
});
console.log("listening on port 8000")
server.listen(8000);

// Listen for the `error` event on `proxy`.
// as we will generate a big bunch of errors
proxy.on('error', function (err, req, res) {
  console.log(err)
  res.writeHead(500, {
    'Content-Type': 'text/plain'
  });
  res.end("Oops");
});

proxy.on('proxyRes', function(proxyRes, req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
});

所以,你需要在res中设置头信息(你可以在proxyRes事件或proxyReq事件中设置)。不要在这些事件的proxyResproxyReq参数中设置。 - gihanchanuka
1
请注意,如果目标已经设置了Access-Control-Allow-Origin,则似乎无法正常工作,因为当代理写入“res”时,您的自定义值将被覆盖。 - Michael Gummelt
它给我报错了:“已被CORS策略阻止:预检请求的响应未通过访问控制检查:它没有HTTP ok状态。” - Deepak Bandela
好的,这个答案是来自2013年的,事情可能有所改变。但我认为你在这里的主要问题是你没有一个200 Ok响应来回应你的OPTION http查询它没有HTTP ok状态,这是另一个问题。 - regilero

6
对于未来遇到此问题的人,这里提供一个更新的答案。结合Michael Gummelt的评论和Nicholas Mitrousis的回答,如果上游代理服务器的响应中设置了与res相同的头,则res上设置的任何头都将被覆盖。所以回答原始问题:
proxy.on('proxyRes', function(proxyRes, req, res) {
 proxyRes.headers["access-control-allow-origin"] = "*";
 proxyRes.headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS";
}

1
即使这个问题已经很老了,但它是谷歌的第一个结果,当前的答案并不是非常有帮助。第一个需要注意的点是`proxyRes`没有`setHeader()`方法。此外,如果你尝试使用`res.setHeader('Header-to-Override', 'new value')`来覆盖`proxyRes`标头,它将不起作用(我认为是由于在此事件被触发后,标头从`proxyRes`复制到`res`)。看来我们不是唯一遇到这个问题的人:https://github.com/http-party/node-http-proxy/issues/1401。以下是我在我的情况下添加额外的`cache-control`标头的解决方案:

proxy.on('proxyRes', function(proxyRes, req, res) {
  if (proxyRes.headers['cache-control']) {
    proxyRes.headers['cache-control'] += ', proxy-revalidate'
  } else {
    proxyRes.headers['cache-control'] = 'proxy-revalidate'
  }
})


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接