Javascript express http代理仍被CORS策略阻止

Javascript express http代理仍被CORS策略阻止,javascript,ajax,node.js,proxy,polymer,Javascript,Ajax,Node.js,Proxy,Polymer,我有一个express服务器静态地为我的Polymer项目服务。我需要进行RESTAPI查询,但是如果我从客户端进行查询,它将被CORS阻止。所以我曾经试着绕过这个问题;我将请求发送给它,它将重定向到具有RESTAPI端点的服务器。这是使用node server.js运行的全部服务器代码: var express = require('express'); var proxy = require('express-http-proxy'); var server = express(); se

我有一个express服务器静态地为我的Polymer项目服务。我需要进行RESTAPI查询,但是如果我从客户端进行查询,它将被CORS阻止。所以我曾经试着绕过这个问题;我将请求发送给它,它将重定向到具有RESTAPI端点的服务器。这是使用
node server.js运行的全部服务器代码:

var express = require('express');
var proxy = require('express-http-proxy');

var server = express();
server.use('/', express.static(__dirname + '/'));
server.listen(8080);
server.use('/rest/api/2/search', proxy('restserver:8877'));
console.log("Server listening on localhost:8080");
当我在浏览器中访问restserver:8877/rest/api/2/search时,它返回一堆json作为“默认”搜索

在客户端,我让iron ajax提出以下请求:

<iron-ajax
            id="getBugs"
            url="/rest/api/2/search"
            params=''
            on-response="handleResponse"
            debounce-duration="300">
        </iron-ajax>

我不明白为什么它会给我这些URL,因为我从来没有引用过它们,为什么它会因为CORS而被阻塞,因为它来自服务器,而不是客户端,这是代理的全部要点。

服务器可能会返回一个
302
重定向,这在所使用的中间件中没有正确处理

阅读更多重定向工作原理:

您可以修改
位置
响应标题以解决CORS问题,也可以尝试:

var proxy = require('http-proxy-middleware');

var restServerProxy = proxy({target: 'http://restserver:8877', autoRewrite: true});

server.use('/rest/api/2/search', restServerProxy);

上面的示例应该自动处理重定向。

服务器可能返回一个
302
重定向,但在使用的中间件中没有正确处理该重定向

阅读更多重定向工作原理:

您可以修改
位置
响应标题以解决CORS问题,也可以尝试:

var proxy = require('http-proxy-middleware');

var restServerProxy = proxy({target: 'http://restserver:8877', autoRewrite: true});

server.use('/rest/api/2/search', restServerProxy);

上述示例应自动处理重定向。

替代解决方案是使用@chimurai提到的http代理中间件

如果要代理到https服务器以避免CORS,请执行以下操作:

const proxy = require('http-proxy-middleware');

app.use('/proxy', proxy({
    pathRewrite: {
       '^/proxy/': '/'
    },
    target: 'https://server.com',
    secure: false
}));

此处安全:需要设置为false以避免无法验证叶子签名的错误。

替代解决方案是使用@chimurai提到的http代理中间件

如果要代理到https服务器以避免CORS,请执行以下操作:

const proxy = require('http-proxy-middleware');

app.use('/proxy', proxy({
    pathRewrite: {
       '^/proxy/': '/'
    },
    target: 'https://server.com',
    secure: false
}));

此处secure:false需要设置以避免无法验证\u LEAF\u签名错误。

您不需要任何代理。因为您正在服务器上调用端点,所以可以将调用服务器的客户端列入白名单。您可以使用
cors
package来实现这一点

https://www.npmjs.com/package/cors
首先,在一个文件中定义CORS策略逻辑(将其命名为
CORS policy logic.js
),然后将其导出,以便在其他文件中使用

const cors = require('cors');

const whitelist = ['http://localhost:8080', 'http://localhost:your_client_url'];

var corsOptionsDelegate = (req, callback) => {
  var corsOptions;
  if (whitelist.indexOf(req.header('Origin')) !== -1) {
    corsOptions = { origin: true };
  } else {
    corsOptions = { origin: false };
  }
  callback(null, corsOptions);
};

exports.cors = cors();
exports.corsWithOptions = cors(corsOptionsDelegate);
现在,导入它并在您定义某个端点的任何位置使用它:

var express = require('express');
const cors = require('./cors-policy-logic.js');

var server = express();
server.use('/', express.static(__dirname + '/'));
server.listen(8080);

server.route('/rest/api/2/search')
  .options(cors.corsWithOptions, (req, res) => { res.sendStatus(200); })
  .get(cors.cors, (req, res, next) => {
     //Your business logic
  });

console.log("Server listening on localhost:8080");

你不需要任何代理。因为您正在服务器上调用端点,所以可以将调用服务器的客户端列入白名单。您可以使用
cors
package来实现这一点

https://www.npmjs.com/package/cors
首先,在一个文件中定义CORS策略逻辑(将其命名为
CORS policy logic.js
),然后将其导出,以便在其他文件中使用

const cors = require('cors');

const whitelist = ['http://localhost:8080', 'http://localhost:your_client_url'];

var corsOptionsDelegate = (req, callback) => {
  var corsOptions;
  if (whitelist.indexOf(req.header('Origin')) !== -1) {
    corsOptions = { origin: true };
  } else {
    corsOptions = { origin: false };
  }
  callback(null, corsOptions);
};

exports.cors = cors();
exports.corsWithOptions = cors(corsOptionsDelegate);
现在,导入它并在您定义某个端点的任何位置使用它:

var express = require('express');
const cors = require('./cors-policy-logic.js');

var server = express();
server.use('/', express.static(__dirname + '/'));
server.listen(8080);

server.route('/rest/api/2/search')
  .options(cors.corsWithOptions, (req, res) => { res.sendStatus(200); })
  .get(cors.cors, (req, res, next) => {
     //Your business logic
  });

console.log("Server listening on localhost:8080");

可能是
expresshttpproxy
只是转发来自客户端的
Origin
头,该头是
http://localhost:8080
,导致终端服务器拒绝它

尝试使用以下命令修改它:

server.use('/rest/api/2/search',proxy('restserver:8877'{
proxyReqOptDecorator(proxyReqOpts){
proxyReqOpts.headers['Origin']='http://accepted.origin.com';
返回proxyReqOpts;
}
}));

从未使用过
express http proxy
,也没有对其进行过测试,所以请告诉我这是否是一个解决方案。另外,我认为按照别人的建议使用可能会简化很多事情。但是我不知道您的开发限制,所以我可能是错的。

可能是
express http proxy
只是简单地转发来自您的客户端的
Origin
头,它是
http://localhost:8080
,导致终端服务器拒绝它

尝试使用以下命令修改它:

server.use('/rest/api/2/search',proxy('restserver:8877'{
proxyReqOptDecorator(proxyReqOpts){
proxyReqOpts.headers['Origin']='http://accepted.origin.com';
返回proxyReqOpts;
}
}));

从未使用过
express http proxy
,也没有对其进行过测试,所以请告诉我这是否是一个解决方案。另外,我认为按照别人的建议使用可能会简化很多事情。但是我不知道您的开发限制,所以我可能错了。

express http proxy和http proxy中间件是两种不同的东西。使用http代理MiddlewareXpress无法解决express http代理问题http代理和http代理中间件是两种不同的东西。使用http代理无法解决express http proxy问题middlewareOP询问的是express http proxy,而不是http proxy middlewareOP询问的是express http proxy,而不是http proxy middlewareOP试图代理第二台服务器,这就是他们使用代理包的原因。您的回答没有回答问题。OP正在尝试代理第二台服务器,这就是他们使用代理包的原因。您的回答没有回答问题。谢谢。这似乎解决了任何CORS问题。不幸的是,
cors
程序包与express http proxy不兼容,这就是为什么需要手动设置这些头。很高兴@FezVrasta在
cors
程序包方面起到了作用,您不必插入
express http proxy
。它是一个独立的中间件,允许您在目标服务器上接受来自精心策划的主机列表的请求,如so
app.use(cors(['http://localhost:8080', 'https://www.mywebsite.com)
。如果您的问题只是api服务器拒绝来自前端的请求,那么它可能会更有用、更简单。在我的例子中,我使用Node.js服务器代理第二个REST api,因此我不能只使用cors包。谢谢,这似乎解决了任何cors问题。不幸的是,
cors
包与express http proxy不兼容,这就是为什么需要手动设置这些头文件。很高兴@FezVrasta Conc成功