2013-04-16 11 views
6

Ho giocato con Backbone nella mia console di Chrome e mi sono imbattuto in un problema interdominio che non riesco a capire.Backbone.js non effettuerà richieste cross-host?

Il padrone di casa che sto connessione a implementa presumibilmente correttamente CORS perché una richiesta XHR grezzo restituisce il JSON atteso:

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

(tronchi 3 eventi progress XHR sulla console con i dati corretti nella risposta)

ma quando lo faccio la seguente con Backbone il suo navigatore web non piace:

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

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

C'è qualcosa che devo fare per dire a Backbone di lavorare con CORS? Sembra che questo errore si sia verificato prima che il browser effettuasse una richiesta, quindi non penso che sia un errore di configurazione del server.

+0

È possibile disattivare stessa politica di origine in Chrome, [qui] (http: // StackOverflow. it/a/3177718/1344509) ha spiegato come disabilitarlo su Chrome. – Ikrom

+0

Grazie per il suggerimento, ma non voglio disabilitarlo (è progettato per funzionare su normali browser Web). – magneticMonster

+0

Quindi forse [questo] (http://stackoverflow.com/a/6487765/1344509) aiuta. – Ikrom

risposta

8

spero uno di questi aiuti (non ho provato ancora):
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 
    }; 
}); 
+1

'xhrFields.withCredentials' si bloccherà in Firefox se si sta effettuando una chiamata sincrona AJAX, ad esempio il caricamento di un modello prima del rendering. Fortunatamente i miei modelli sono sullo stesso dominio quindi potrei semplicemente racchiudere il precedente in 'if (originalOptions.async! == false)' block – kasztelan

+0

Dove dovrei aggiungere l'aggiornamento del metodo di sincronizzazione? In backbone.js O il mio script? – dang

+0

@dang Nel tuo codice javascript, non Backbonejs – Ikrom

0

Si scopre gli URL sono stato richiedente Backbone erano leggermente diversi da quelli richiesti tramite XHR (mancava un queryarg). Ciò ha causato il server a 500, che non ha le intestazioni CORS. Chrome non ha mostrato la richiesta HTTP nella scheda di rete del pannello di debug, quindi ero estremamente confuso.

La riparazione del server 500 sul server ha funzionato di nuovo.

5

hey si può usare qualcosa di simile a:

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

la chiave è che abbiamo bisogno di usare 'jsonp'

+0

Ha funzionato perfettamente! – pastullo

+0

Grazie signore! 'jsonp' risolto il mio problema –

+0

Grazie @heridev .. risolto il mio problema .. – Manivannan