我有一台静态服务器静态服务我的Polymer项目。我有一个REST API查询,我需要做,但如果我从客户端进行,它将被CORS阻止。所以我用express-http-proxy试图解决这个问题;我将请求发送给它,它重定向到具有REST API端点的服务器。这是与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>
在脚本部分,我在this.$.getBugs.generateRequest()
函数中使用ready
来发送请求。所以我加载它,期望请求不被CORS阻止,因为......它正由服务器代理。相反,Chrome devtools给了我这个:
XMLHttpRequest cannot load http://restserver:8877/secure/MyJiraHome.jspa. Redirect from 'http://restserver:8877/secure/MyJiraHome.jspa' to 'http://restserver:8877/secure/Dashboard.jspa' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
我不明白为什么它会给我这些URL,因为我从来没有引用它们,以及为什么它因CORS而阻塞,因为它来自服务器而不是客户端,这是代理的全部要点。 / p>
答案 0 :(得分:0)
服务器可能正在返回302
重定向,但在使用的中间件中未正确处理。
详细了解重定向的工作原理:https://en.wikipedia.org/wiki/HTTP_location
您可以修改Location
响应标头以克服CORS问题,或者您可以尝试:
var proxy = require('http-proxy-middleware');
var restServerProxy = proxy({target: 'http://restserver:8877', autoRewrite: true});
server.use('/rest/api/2/search', restServerProxy);
以上示例应自动处理重定向。
答案 1 :(得分:0)
替代解决方案是使用@chimurai提到的 http-proxy-middleware 。
如果您想代理 https 服务器以避免CORS:
const proxy = require('http-proxy-middleware');
app.use('/proxy', proxy({
pathRewrite: {
'^/proxy/': '/'
},
target: 'https://server.com',
secure: false
}));
此处需要设置 secure:false 以避免 UNABLE_TO_VERIFY_LEAF_SIGNATURE 错误。
答案 2 :(得分:0)
可能是 express-http-proxy
只是转发来自客户端的 Origin
标头,即 http://localhost:8080
,导致终端服务器拒绝它。
尝试用 proxyReqOptDecorator
修改它:
server.use('/rest/api/2/search', proxy('restserver:8877', {
proxyReqOptDecorator(proxyReqOpts) {
proxyReqOpts.headers['Origin'] = 'http://accepted.origin.com';
return proxyReqOpts;
}
}));
从未使用过 express-http-proxy
并且没有对其进行测试,所以如果这不是解决方案,请告诉我。另外我认为按照其他人的建议使用 cors
可以简化很多事情。但我不知道你的发展限制,所以我可能是错的。
答案 3 :(得分:-1)
您不需要任何代理。由于您在服务器上调用端点,因此您可以将客户端列入白名单以调用您的服务器。您可以使用 cors
包来做到这一点。
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");