Aktivieren der CORS (Cross-Origin Resource Sharing) im Express.js-Framework auf node.js.

101

Ich versuche, in node.js einen Webserver zu erstellen, der domänenübergreifendes Scripting unterstützt und gleichzeitig statische Dateien aus einem öffentlichen Verzeichnis bereitstellt. Ich verwende die Datei express.js und bin mir nicht sicher, wie ich domänenübergreifendes Scripting zulassen soll ( Access-Control-Allow-Origin: *).

Ich habe diesen Beitrag gesehen , den ich nicht hilfreich fand.

var express = require('express')
  , app = express.createServer();

app.get('/', function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
});

app.configure(function () {
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(app.router);
});

app.configure('development', function () {

    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function () {


    var oneYear = 31557600000;
    //    app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler());
});

app.listen(8888);
console.log('express running at http://localhost:%d', 8888);
Kerl
quelle
Beachten Sie die app.all vs app.get. Es ist OPTIONS Anfrage nicht GET
Shimon Doodkin
siehe local-Webserver für ein Beispiel eines einfachen Knotens, statische Web - Server , die CORS unterstützt
Lloyd
Weitere Informationen finden Sie unter enable-cors.org/server_apache.html
Mostafa,

Antworten:

159

Schauen Sie sich das Beispiel von enable-cors.org an :

Gehen Sie in Ihrer ExpressJS-App auf node.js mit Ihren Routen wie folgt vor:

app.all('/', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
 });

app.get('/', function(req, res, next) {
  // Handle the get for this route
});

app.post('/', function(req, res, next) {
 // Handle the post for this route
});

Der erste Aufruf ( app.all) sollte vor allen anderen Routen in Ihrer App erfolgen (oder zumindest vor denen, für die Sie CORS-fähig sein möchten).

[Bearbeiten]

Wenn die Header auch für statische Dateien angezeigt werden sollen, versuchen Sie dies (stellen Sie sicher, dass dies vor dem Aufruf von use(express.static()):

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

Ich habe dies mit Ihrem Code getestet und die Header für Assets aus dem publicVerzeichnis abgerufen :

var express = require('express')
  , app = express.createServer();

app.configure(function () {
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "X-Requested-With");
      next();
    });
    app.use(app.router);
});

app.configure('development', function () {
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function () {
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler());
});

app.listen(8888);
console.log('express running at http://localhost:%d', 8888);

Sie können die Funktion natürlich in ein Modul packen, um so etwas zu tun

// cors.js

module.exports = function() {
  return function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
  };
}

// server.js

cors = require('./cors');
app.use(cors());
Michelle Tilley
quelle
Hey, danke für deine Antwort. Ich habe getan, was Sie vorgeschlagen haben (erster Teil, sehe aber in den Anforderungsheadern immer noch keinen Unterschied). Ich habe meinen aktuellen Code oben angehängt. Können Sie erklären, wie ich den Rest Ihrer Lösung in diese integrieren kann?
Guy
1
Ich bin überrascht , dass, da Sie useing app.routervor , express.staticdass es die Header für statische Dateien nicht ändern wird; Auf jeden Fall habe ich meine Antwort so aktualisiert, dass sie funktioniert.
Michelle Tilley
Vielen Dank! Ich sehe, dass du recht hast. Die Assets werden vom Server mit den angeforderten Headern abgerufen. Möglicherweise war mir mein eigentliches Problem nicht klar. Ich versuche, mit dem Befehl get einen API-Aufruf an einen externen Server zu senden. und hier erhalte ich den Fehler: XMLHttpRequest kann SOMEURL.com nicht laden . Origin localhost: 8888 ist von Access-Control-Allow-Origin nicht zulässig.
Guy
Ich kann falsch verstehen. Haben Sie die Kontrolle über den Server bei SOMEURL.com?
Michelle Tilley
Entschuldigung, ich verstehe Ihre Antwort jetzt vollständig. Vielen Dank. Ich schätze Ihre Hilfe :)
Guy
58

Nach der @ Michael Tilley-Lösung hat es anscheinend zunächst bei mir nicht funktioniert. Ich weiß nicht warum, vielleicht verwende ich Chrome und eine andere Version des Knotens. Nach einigen kleinen Änderungen funktioniert es jetzt für mich.

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

Falls jemand mit einem ähnlichen Problem wie ich konfrontiert ist, kann dies hilfreich sein.

TonyTakeshi
quelle
Beachten Sie die app.all vs app.get. Es ist OPTIONS Anfrage nicht GET
Shimon Doodkin
Dies funktioniert bei mir (ich rufe Objekte mit Backbone ab). Ich versuche herauszufinden, ob es in IE 8 funktionieren wird ... scheint so, aber ich weiß nicht, ob für dieses "XDomainRequest" -Ding etwas Besonderes erforderlich ist ... developer.mozilla.org/en- US / docs / HTTP /…
Adam Loving
EINIGE INFORMATIONEN FÜR ZUKÜNFTIGE BENUTZER: Ich leite meinen Domain-Namen auf ein Heroku-Repo um, weshalb ich auf dieses Problem gestoßen bin. Wie auch immer, die erste Antwort funktionierte lokal, aber nicht nachdem ich sie an Heroku gesendet hatte. Diese Antwort funktionierte jedoch, nachdem ich auf Heroku gedrückt hatte.
Kris Hollenbeck
@KrisHollenbeck Das funktioniert bei Heroku nicht, hast du noch etwas gemacht?
Ben Craig
@ BenCraig, Nein, aber es hat nach dem ersten Versuch tatsächlich aufgehört, für mich zu arbeiten. Ich habe also immer noch dieses Problem.
Kris Hollenbeck
11

Versuchen Sie es mit diesen cors npm Modulen.

var cors = require('cors')

var app = express()
app.use(cors())

Dieses Modul bietet viele Funktionen zur Feinabstimmung der Cors-Einstellungen, z. B. Whitelist für Domänen, Aktivierung von Cors für bestimmte APIs usw.

Zahid Rahman
quelle
2

Ich benutze das:

var app = express();

app
.use(function(req, res, next){
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'X-Requested-With');
    next();
})
.options('*', function(req, res, next){
    res.end();
})
;

h.readFiles('controllers').forEach(function(file){
  require('./controllers/' + file)(app);
})
;

app.listen(port);
console.log('server listening on port ' + port);

Dieser Code setzt voraus, dass sich Ihre Controller im Controller-Verzeichnis befinden. Jede Datei in diesem Verzeichnis sollte ungefähr so ​​aussehen:

module.exports = function(app){

    app.get('/', function(req, res, next){
        res.end('hi');
    });

}
Elmer
quelle
1

Empfehlen Sie die Verwendung des Cors Express-Moduls. Auf diese Weise können Sie Domänen auf die Whitelist setzen, Domänen speziell für Routen zulassen / einschränken usw.

Jerome Anthony
quelle
0

Sie müssen festlegen Access-Control-Allow-Credentials: true, ob Sie "Cookie" über "Anmeldeinformationen" verwenden möchten.

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});
Herzoggott
quelle
0
app.use(function(req, res, next) {
var allowedOrigins = [
  "http://localhost:4200"
];
var origin = req.headers.origin;
console.log(origin)
console.log(allowedOrigins.indexOf(origin) > -1)
// Website you wish to allow to
if (allowedOrigins.indexOf(origin) > -1) {
  res.setHeader("Access-Control-Allow-Origin", origin);
}

// res.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");

// Request methods you wish to allow
res.setHeader(
  "Access-Control-Allow-Methods",
  "GET, POST, OPTIONS, PUT, PATCH, DELETE"
);

// Request headers you wish to allow
res.setHeader(
  "Access-Control-Allow-Headers",
  "X-Requested-With,content-type,Authorization"
);

// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader("Access-Control-Allow-Credentials", true);

// Pass to next layer of middleware
next();

});

Fügen Sie diesen Code in Ihre Datei index.js oder server.js ein und ändern Sie das zulässige Ursprungsarray entsprechend Ihren Anforderungen.

Atyos
quelle
-6

Ein weiterer Schritt, den ich unternehmen musste, war das Umschalten meiner URL von auf http://localhostnachhttp://127.0.0.0

user3795430
quelle
Worauf beziehen Sie sich?
Blunderfest