Mic*_*ael 1 ajax node.js cors express backbone.js
我正在尝试为我的骨干应用程序实现跨域设置.
我的服务器(express.js)允许跨域和凭证:
var allowCrossDomain = function(req, res, next) {
var allowedHost = [
'http://localhost:3001',
'http://localhost:7357'
];
if(allowedHost.indexOf(req.headers.origin) !== -1) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin)
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version');
next();
} else {
res.send({auth: false});
}
}
app.configure(function(){
....
app.use(allowCrossDomain);
....
});
Run Code Online (Sandbox Code Playgroud)
我的客户端(backbone.js)也配置为接受跨域:
define(["backbone", "jquery", "underscore"], function (BB, $, _) {
return BB.Model.extend({
idAttribute: "_id",
initialize: function () {
var that = this;
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.crossDomain ={
crossDomain: true
};
options.xhrFields = {
withCredentials: true
};
});
}
});
});
Run Code Online (Sandbox Code Playgroud)
现在,当我测试我的代码(假设POST请求)时,我有一个非常特殊的行为:
var contacts = new Contacts;
contacts.create({'name': 'my name'});
Run Code Online (Sandbox Code Playgroud)
浏览器返回此消息:
选项... 404(未找到)jquery.js:8419
这完全让我感到困惑,因为OPTIONS骨干网不支持http方法?
最有可能的是,您的Express路线仅指定GET和/或POST方法.例如,
app.post('/some/api/method', function(req, res) { ... });
Run Code Online (Sandbox Code Playgroud)
这意味着您只为POSTs到/ some/api /方法定义了一个路由处理程序,而使用任何其他方法(如GET或OPTIONS)的请求将返回404.
在某些情况下(例如发送自定义HTTP标头),使用CORS对跨源URL的XHR请求要求浏览器必须首先发出OPTIONS请求以查看是否允许跨域请求.只有当OPTIONS请求成功(带有 CORS头的HTTP 200 )时,浏览器才会发出实际请求.
由于您只POST在服务器上定义了路由,因此OPTIONS请求失败,浏览器不会发出请求.您需要正确回复OPTIONS请求:
app.options('/some/api/method', function(req, res) {
// At this point, the `allowCrossDomain()` middleware will already have
// taken care of the CORS stuff, so just return OK.
res.send(200);
});
Run Code Online (Sandbox Code Playgroud)
现在,预检OPTIONS检查将通过,因此将对POST处理程序进行实际请求.
关于您的代码的额外评论:
indexOf需要在每个请求上缓慢迭代数组,其中使用对象允许快速查找.(请记住,JavaScript对象将其键存储在类似字典的数据结构中.)allowedHosts 外部定义- 它们不会更改,因此每次allowCrossDomain调用时都不需要创建新对象(需要垃圾回收).
var allowedHost = {
'http://localhost:3001': true,
'http://localhost:7357': true
};
var allowCrossDomain = function(req, res, next) {
if(allowedHost[req.headers.origin]) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin)
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version');
next();
} else {
res.send(403, {auth: false});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8758 次 |
| 最近记录: |