2012-04-09 1 views
11

Sto sviluppando un'applicazione sul mio pc locale. Il frontend dovrebbe essere costruito con spinejs e il backend-api con node.js. spina dorsale è in esecuzione sulla porta 9294 e node.js è in esecuzione sulla porta 3000. nella colonna vertebrale che ho aggiunto al mio modello seguente:spine, node.js (espresso) e Access-Control-Allow-Origin

@url: "http:localhost:3000/posts" 

e nel mio Server Express

app.get('/posts', function(req, res){ 
    console.log("giving ALL the posts"); 
    res.header("Access-Control-Allow-Origin", "*") 
    res.json(posts); 
}); 

Ma sono sempre ottenendo il seguente erro in cromo:

XMLHttpRequest cannot load http://localhost:3000/posts. Origin http://localhost:9294 is not allowed by Access-Control-Allow-Origin. 

che cosa devo fare che posso accedere al mio api correttamente? Anche se aggiungendo l'intestazione nelle risposte, il problema si risolve.

+1

Avete ispezionato l'intestazione di risposta per confermare che l'intestazione è infatti stato impostato? Inoltre, jQuery usa il comando HTTP 'OPTIONS' per rilevare pre-auth; assicurati che express stia rispondendo a quel Verb HTTP anche – tkone

+0

onestamente, sembra che la mia richiesta non raggiunga mai il mio server node.js. Ho aggiunto una dichiarazione di debug in app.get() PRIMA che qualcosa sia stato inviato al client. Quando accedo alla mia API direttamente sopra l'url posso vedere la dichiarazione ma non quando accedo tramite la colonna vertebrale – soupdiver

+0

YOu dovrebbe usare qualcosa come charles per assicurarsi che questo accada. Facciamo un sacco di cose x-domain qui ed è frustrante finché non vedi che l'intestazione NON è impostata. – tkone

risposta

16

app.get risponderà solo alle richieste GET. Se il browser esegue il preflight con una richiesta OPTIONS, express invierà un errore perché non ha alcun listener per tali richieste. Prova ad aggiungere questo codice in aggiunta ai tuoi e vedere se funziona:

app.options('/posts', function(req, res){ 
    console.log("writing headers only"); 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.end(''); 
}); 

anche notare: se si sta inviando i biscotti con la richiesta (withcredentials=true), poi l'intestazione Access-Control-Allow-Origin non può essere *, deve essere l'esatto il valore nell'intestazione Origin che il browser aggiunge automaticamente alla richiesta Ajax in questo modo:

res.header("Access-Control-Allow-Origin", req.headers.origin); 

Questo è per ragioni di sicurezza - se stai facendo qualcosa che richiede i cookie, allora è più probabile che si vuole effettivamente verificare che il origin sia un permesso sito Web per evitare CSRF attacks.

+0

grazie amico! Non avevo il metodo OPTIONS sullo schermo .... ora lavoro :) – soupdiver

15

Questo middleware consentirà a CORS l'utilizzo di Express, la chiave sta rilevando la richiesta di preflight OPTIONS e restituisce una risposta per evitare le query del database 404 o duplicate. Vedere risorsa: http://cuppster.com/2012/04/10/cors-middleware-for-node-js-and-express/

var methodOverride = require('method-override'); 
app.use(methodOverride()); 

// ## CORS middleware 
// see: http://stackoverflow.com/questions/7067966/how-to-allow-cors-in-express-nodejs 
var allowCrossDomain = function(req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); 

    // intercept OPTIONS method 
    if ('OPTIONS' == req.method) { 
     res.send(200); 
    } 
    else { 
     next(); 
    } 
}; 
app.use(allowCrossDomain); 
+1

Infine, uno che funziona davvero! Grazie! –

+2

methodOverride non è più in bundle con Express a partire dalla versione 4, quindi sarà necessario includere "method-override" nel pacchetto package.json, quindi invece di 'app.use (express.methodOverride())', usare 'var methodOverride \t = require ('metodo-sovrascrittura'); app.use (methodOverride()); ' –