Backbone.js IE中的fetch()问题

时间:2013-01-11 08:14:29

标签: django internet-explorer backbone.js fetch

我正在使用后端的Django和前端的Backbone.js构建一个Web应用程序

当我尝试从服务器获取数据时,我遇到了IE问题。当我在IE中运行我的HTML页面时,集合提取总是调用错误函数。

我的代码:

$(function(){

var Chapter = Backbone.Model.extend({});

var Chapters = Backbone.Collection.extend({
    model: Chapter,
    url: 'http://ip.olya.ivanovss.info/chapters'
});

var chapters = new Chapters();

var Router = new (Backbone.Router.extend({
    routes: {
        "": "choose_activity",
        "/": "choose_activity"
    },

    choose_activity: function () {
        chapters.fetch({
            success: function () {
                AppView.render();
            },
            error: function() {
                alert('error');
            }
        });
    }
}))();

var AppView = new (Backbone.View.extend({
    el: '.popup',
    templates: {
        choose_activity: Handlebars.compile($('#tpl-activities').html())
    },
    render: function () {
        this.$el.html(this.templates["choose_activity"]({ chapters: chapters.toJSON()}));
    }
}))();

Backbone.history.start();
});

Django的观点:

def chapters(request):
    chapters = list(Chapter.objects.order_by('id'))
    response = HttpResponse(json.dumps(chapters, default=encode_myway), mimetype='text/plain')
    if request.META.get('HTTP_ORIGIN', None) in ('http://localhost', 'http://html.olya.ivanovss.info', 'http://10.0.2.2'):
        response['Access-Control-Allow-Origin'] = request.META['HTTP_ORIGIN']
    return response

提前谢谢

1 个答案:

答案 0 :(得分:0)

IE7不支持CORS。

有两种解决方法。 EASY方式是您的API上的代理。我的Python很生疏(我是一个Node / PHP开发者),但我确信有一百万个资源可以解决这个问题。这样做的好处是你不必触摸API。但这意味着您的本地服务器必须使用CURL并从API服务器返回每个请求。

第二个(而且服务器密集程度更低)是JSONP! JSONP的想法是它使用您指定的URL将<script>附加到文档。 jQuery附加一个?callback=jQueryNNN,其中NNN是一个随机数。如此有效地加载<script>时,它调用jQueryNNN('The Response Text')并且jQuery知道从那里解析响应。关于这一点的坏处是你必须将你的所有响应都包含在API方面(如果你刚刚开始,这非常简单,如果你已经建立了基础设施,那就不那么容易了。)

关于JSONP的令人讨厌的事情是,它本质上是你无法进行POST / PUT / DELETE。但是,如果您有权访问API,则可以模拟它:

Backbone.emulateHTTP = true;

model.save();  // POST to "/collection/id", with "_method=PUT" + header.

将JSONP与Backbone集成非常简单(小秘密Backbone.sync使用jQuery的$.ajax()并且选项参数转发到jQuery;))。

对于访问交叉原点的每个模型/集合,您可以添加su

var jsonpSync = function (method, model, options) {
    options.timeout = 10000; // for 404 responses
    options.dataType = "jsonp";
    return Backbone.sync(method, model, options);
};

在每个集合和模型中,交叉起源是什么:

var MyCollection = Backbone.Collection.extend({
    sync  : jsonpSync
});

或者只是覆盖整个Backbone同步

Backbone.__sync = Backbone.sync;

var jsonpSync = function (method, model, options) {
    options.timeout = 10000; // for 404 responses
    options.dataType = "jsonp";
    return Backbone.__sync(method, model, options);
};

Backbone.sync = jsonpSync;

在服务器端,您可以:this返回JSONP响应(此处粘贴的副本):

def randomTest(request):
    callback = request.GET.get('callback', '')
    req = {}
    req ['title'] = 'This is a constant result.'
    response = json.dumps(req)
    response = callback + '(' + response + ');'
    return HttpResponse(response, mimetype="application/json")