2012-04-09 3 views
11

Ich entwickle eine App auf meinem lokalen PC. Das Frontend sollte mit spinejs und das Backend-API mit node.js erstellt werden. Spine läuft auf Port 9294 und node.js läuft auf Port 3000. in Spine Ich habe folgendes mein Modell hinzugefügt:spine, node.js (express) und Access-Control-Allow-Origin

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

und in meinem Express Server

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

Aber ich bin immer die folgende erro in Chrom bekommen:

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

Was muss ich tun, dass ich richtig mein api zugreifen kann? Obwohl ich den Header in den Antworten hinzufüge, behebt das Problem.

+1

Haben Sie die Antwort-Header überprüft, um zu bestätigen, dass der Header tatsächlich eingestellt wird? Außerdem verwendet jQuery den HTTP-Befehl "OPTIONS", um Pre-Auth zu erkennen. Stellen Sie sicher, dass express auch auf dieses HTTP-Verb reagiert. – tkone

+0

Ehrlich gesagt, scheint meine Anfrage niemals meinen node.js-Server zu erreichen. Ich habe eine Debug-Anweisung in app.get() hinzugefügt, bevor irgendetwas an den Client gesendet wird. Wenn ich direkt über die URL auf meine API zugreife, kann ich die Aussage sehen, aber nicht beim Zugriff über den Backbone – soupdiver

+0

Sie sollten etwas wie Charles verwenden, um sicherzustellen, dass dies geschieht. Wir machen eine Menge X-Domain-Sachen hier und es ist frustrierend, bis man sieht, dass der Header NICHT gesetzt ist. – tkone

Antwort

16

app.get reagiert nur auf GET Anfragen. Wenn der Browser es mit einer OPTIONS Anfrage Preflight ist, wird Express einen Fehler senden, da es keine Listener für diese Anforderungen hat. Versuchen Sie, diesen Code zusätzlich zu Ihrem und sehen, ob es funktioniert:

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

Beachten Sie auch: wenn Sie senden Cookies mit der Anfrage (withcredentials=true), dann wird der Access-Control-Allow-Origin Header nicht * sein kann, muss es genau sein Wert im Origin-Header, der Browser auf den ajax-Request fügt automatisch wie folgt:

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

Dies ist aus Sicherheitsgründen - wenn Sie etwas tun, die Cookies benötigt, dann ist es wahrscheinlicher, dass Sie wollen überprüfen Sie tatsächlich, dass die origin eine Erlaubnis ist Ed Website um zu vermeiden, CSRF attacks.

+0

danke dude! Ich hatte nicht die OPTIONS-Methode auf dem Bildschirm .... jetzt arbeiten :) – soupdiver

15

Mit dieser Middleware kann CORS Express verwenden, der Schlüssel erkennt die Preflight-Anforderung OPTIONS und gibt eine Antwort zurück, um 404- oder doppelte Datenbankabfragen zu vermeiden. Siehe Ressource: 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

Endlich, eine, die tatsächlich funktioniert! Vielen Dank! –

+2

methodOverride ist nicht mehr mit Express ab Version 4 gebündelt, Sie müssen daher "method-override" in Ihre package.json aufnehmen, dann verwenden Sie 'var methodOverride anstelle von' app.use (express.methodOverride()) '' \t = require ('method-override'); app.use (methodOverride()); ' –

Verwandte Themen