【问题标题】:Backbone.js won't make cross-host requests?Backbone.js 不会发出跨主机请求?
【发布时间】:2013-04-09 02:26:25
【问题描述】:

我一直在我的 Chrome 控制台中使用 Backbone,并遇到了一个我无法解决的跨域问题。

我要连接的主机大概正确地实现了 CORS,因为原始 XHR 请求返回了预期的 JSON:

var http = new XMLHttpRequest();
http.open('GET', 'http://example.com:3000/entities/item/15.json', true);
http.onreadystatechange = function(evt) { console.log(evt); }
http.send();

(在控制台上记录 3 个 XHR 进度事件,并在响应中包含正确的数据)

但是当我使用 Backbone 执行以下操作时,浏览器不喜欢它:

var Item = Backbone.Model.extend({});
var ItemsCollection = Backbone.Collection.extend({
  model: Item,
  url: 'http://example.com:3000/entities/item/'
});
var items = new ItemsCollection();
items.fetch();

(返回XMLHttpRequest cannot load http://example.com:3000/entities/item/. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.

我需要做些什么来告诉 Backbone 使用 CORS?这个错误似乎在浏览器发出请求之前就已经出现了,所以我认为这不是服务器配置错误。

【问题讨论】:

  • 您可以在 Chrome 中禁用同源策略,here 解释了如何在 Chrome 上禁用它。
  • 感谢您的提示,但我不想禁用它(这是为在常规网络浏览器上运行而设计的)。
  • 那么也许this 有帮助。
  • 是的,就像我在问题中所说的那样,CORS 在服务器端可以正常工作,因为浏览器能够使用标准 XMLHttpRequest 发出请求。

标签: javascript google-chrome backbone.js cross-domain


【解决方案1】:

我希望其中一项能有所帮助(我还没有尝试过):
1.Overriding Backbone.js sync to allow Cross Origin

(function() {
  var proxiedSync = Backbone.sync;
  Backbone.sync = function(method, model, options) {
    options || (options = {});
    if (!options.crossDomain) {
      options.crossDomain = true;
    }
    if (!options.xhrFields) {
      options.xhrFields = {withCredentials:true};
    }
    return proxiedSync(method, model, options);
  };
})();

2。 Cross domain CORS support for backbone.js

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    options.crossDomain ={
        crossDomain: true
    };
    options.xhrFields = {
        withCredentials: true
    };
});

【讨论】:

  • xhrFields.withCredentials 如果您正在进行同步 AJAX 调用(例如在渲染之前加载模板),则会在 Firefox 中崩溃。幸运的是,我的模板在同一个域中,所以我可以将上面的内容包装在 if(originalOptions.async !== false) 块中
  • 我应该在哪里添加同步方法更新?在backbone.js 或我的脚本中?
【解决方案2】:

嘿,你可以使用类似的东西:

 var PostsCollection = Backbone.Collection.extend({
   initialize: function(models, options) {
     //this.id = options.id;
   },
   url: 'http://myapi/api/get_posts/?count=8',
 });

 posts = new PostsCollection();
 posts.fetch({
   dataType: 'jsonp',
   success : function (data) {
     console.log(data);
   }
 });

关键是我们需要使用'jsonp'

【讨论】:

    【解决方案3】:

    事实证明,我使用 Backbone 请求的 URL 与通过 XHR 请求的 URL 略有不同(它们缺少查询参数)。这导致服务器为 500,它没有 CORS 标头。 Chrome在调试面板的网络选项卡中根本没有显示HTTP请求,所以我非常困惑。

    在服务器上修复 500 后,这项工作又可以正常工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 2020-12-31
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      相关资源
      最近更新 更多