2013-01-11 4 views
2

Je construis une application web avec Django sur back-end et Backbone.js sur le frontalBackbone.js Problèmes avec fetch() dans IE

J'ai des problèmes avec IE quand je suis en train de chercher les données du serveur. Lorsque j'exécute ma page HTML dans IE, l'extraction de collection invoque toujours la fonction d'erreur.

Mon code:

$(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(); 
}); 

Voir 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 

Nous vous remercions à l'avance

+2

Quel IE? IE8 et 9 prennent uniquement en charge CORS d'une manière non standard (comme décrit [ici] (http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds .aspx)) – robertklep

+0

Merci, ces informations vous ont aidé à résoudre le problème dans IE8. Peut-être qu'il y a un moyen de le faire fonctionner dans IE7 aussi? – olya

+0

Peut-être [this] (http://stackoverflow.com/questions/10654955/need-a-workaround-for-cross-domain-ajax-post-in-ie7) a quelques conseils utiles. – robertklep

Répondre

0

IE7 ne supporte pas CORS.

Il existe 2 façons de contourner le problème. Le moyen EASY est le proxy sur votre API. Mon Python est rouillé (je suis un développeur Node/PHP), mais je suis sûr qu'il y a des ressources d'un million et un sur la façon de le faire. La bonne chose à ce sujet est que vous n'avez pas à toucher à l'API. Mais cela signifie que votre serveur local doit CURL et retourner chaque requête de votre serveur API.

Et deuxième (et beaucoup moins de manière intensive de serveur) est JSONP! L'idée de JSONP est qu'il ajoute un <script> au document avec l'URL que vous spécifiez. jQuery ajoute un ?callback=jQueryNNNNNN est un nombre aléatoire. Donc, lorsque le <script> se charge, il appelle jQueryNNN('The Response Text') et jQuery sait analyser la réponse à partir de là. La mauvaise chose à ce sujet est que vous devez envelopper toutes vos réponses du côté de l'API (ce qui est super facile si vous ne faites que commencer, pas si facile si vous avez déjà une infrastructure construite). Ce qui est ennuyeux à propos de JSONP, c'est que vous ne pouvez pas faire un POST/PUT/DELETE. Mais vous pouvez l'imiter si vous avez accès à l'API:

Backbone.emulateHTTP = true; 

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

Intégrer JSONP avec Backbone est assez simple (peu Backbone.sync secrète utilise $.ajax() et les paramètres des options de jQuery en avant vers jQuery;)).

Pour chacun de vos modèles/collections d'accéder à une origine croisée, vous pouvez ajouter une su

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

Dans chaque collection et modéliser ce qui fait croix d'origine:

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

Ou tout simplement écraser l'ensemble de synchronisation 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; 

du côté du serveur, vous pouvez faire: this pour renvoyer une réponse JSONP (copie collée ici):

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") 
Questions connexes