我试图做Backbone.js的从我的node.js服务器获取。 然而,我在控制台中出现以下错误:
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
我增加了以下我的node.js服务器:
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', "http://localhost");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
};
app.configure(function() {
app.use(allowCrossDomain);
});
但它仍然返回相同的错误。 然而,即使这样做的工作,它似乎并不像人们理想的解决方案,因为我想来自全国各地的用户能够发送请求。
如果你希望每个人都能够访问节点的应用程序,然后尝试使用
res.header('Access-Control-Allow-Origin', "*")
这将允许来自任何来源的请求。 该CORS使网站有大量的信息在不同的访问控制允许标题和如何使用它们。
您使用的是Chrome我,请看看这个关于本地主机和访问控制允许来源错误的bug。 还有另外一个在这里StackOverflow的问题 ,详细说明这个问题。
如果你正在抓取打电话到localhost,我猜是node.js的在同一个目录下运行作为您的骨干代码,比它最有可能是对http://localhost:3000
或类似的东西。 比这应该是你的模型:
var model = Backbone.Model.extend({
url: '/item'
});
而在你的Node.js你现在不得不接受像这样的电话:
app.get('/item', function(req, res){
res.send('some info here');
});
有2次调用,需要设置正确的头。 最初有一个飞行前检查,所以你需要这样的东西...
app.get('/item', item.list);
app.options('/item', item.preflight);
然后有以下功能...
exports.list = function (req, res) {
Items.allItems(function (err, items) {
...
res.header('Access-Control-Allow-Origin', "*"); // TODO - Make this more secure!!
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST');
res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept');
res.send(items);
}
);
};
并为飞行前检查
exports.preflight = function (req, res) {
Items.allItems(function (err, items) {
res.header('Access-Control-Allow-Origin', "*"); // TODO - Make this more secure!!
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST');
res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept');
res.send(200);
}
);
};
您可以巩固res.header()代码到一个单一的功能,如果你想。
同样如上所述,要小心使用res.header(“访问控制允许来源”,“*”),这意味着任何人都可以访问您的网站!
通过本地主机,你必须使用null
原点。 我建议你创建允许的主机列表,检查请求的Host
头。 如果它是由清单载,然后通过本地主机发送回
res.header('Access-Control-Allow-Origin', "null");
由任何其他域的
res.header('Access-Control-Allow-Origin', hostSentByTheRequestHeader);
如果不是由列表包含,然后发回服务器的主机名,因此浏览器将隐藏通过这些请求的响应。
这是更安全,因为允许起源*,让大家的凭证将能够例如窃取登录用户等的配置文件数据的...
所以总结是这样的:
if (reqHost in allowedHosts)
if (reqHost == "http://localhost")
res.header('Access-Control-Allow-Origin', "null");
else
res.header('Access-Control-Allow-Origin', reqHost);
else
res.header('Access-Control-Allow-Origin', serverHost);
是最安全的解决方案,如果你想允许多个其他域来访问你的页面。 (我想你能弄清楚如何获得该主机请求头和node.js中的服务器主机)
这种方法解决了我的问题,允许多个域
app.use(function(req, res, next) {
var allowedOrigins = ['http://127.0.0.1:8020', 'http://localhost:8020', 'http://127.0.0.1:9000', 'http://localhost:9000'];
var origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin);
}
//res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:8020');
res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', true);
return next();
});