Come abilitare la condivisione delle risorse tra le origini (CORS) nel framework express.js su node.js


101

Sto cercando di creare un server web in node.js che supporterà lo scripting tra domini, fornendo comunque file statici da una directory pubblica. Sto usando express.js e non sono davvero sicuro di come consentire lo scripting interdominio ( Access-Control-Allow-Origin: *).

Ho visto questo post , che non ho trovato utile.

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

Notare app.all vs app.get. È richiesta OPZIONI non OTTENERE
Shimon Doodkin

vedere il server web locale per un esempio di un nodo semplice, server web statico che supporta CORS
Lloyd

vedi enable-cors.org/server_apache.html per maggiori informazioni
Mostafa

Risposte:


159

Guarda l'esempio da enable-cors.org :

Nella tua app ExpressJS su node.js, esegui le seguenti operazioni con i tuoi percorsi:

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

La prima chiamata ( app.all) dovrebbe essere fatta prima di tutte le altre rotte nella tua app (o almeno quelle che vuoi che siano abilitate CORS).

[Modificare]

Se vuoi che le intestazioni vengano visualizzate anche per i file statici, prova questo (assicurati che sia prima della chiamata a 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();
});

L'ho testato con il tuo codice e ho ottenuto le intestazioni sulle risorse dalla publicdirectory:

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

Potresti, ovviamente, impacchettare la funzione in un modulo in modo da poter fare qualcosa di simile

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

Ehi, grazie per la tua risposta. Ho fatto quello che hai suggerito (prima parte, ma ancora non vedo differenze nelle intestazioni della richiesta) Ho allegato il mio codice corrente sopra. puoi spiegare come posso integrare il resto della tua soluzione?
Guy

1
Sono sorpreso che, dato che si sta useing app.routerprima express.staticche non modifica le intestazioni per i file statici; in ogni caso, ho aggiornato la mia risposta in modo che funzioni.
Michelle Tilley

Grazie! Vedo che hai ragione. Le risorse vengono ottenute dal server con le intestazioni richieste. Potrei non essere stato chiaro sul mio vero problema. Sto cercando di effettuare una chiamata API a un server esterno con il comando get. ed è qui che ottengo l'errore: XMLHttpRequest non può caricare SOMEURL.com . Origin localhost: 8888 non è consentito da Access-Control-Allow-Origin.
Guy

Potrei essere un malinteso. Hai il controllo del server su SOMEURL.com?
Michelle Tilley

Scusa, ho capito completamente la tua risposta ora. Molte grazie. Apprezzo il tuo aiuto :)
Guy

58

Seguendo la soluzione di @Michelle Tilley, a quanto pare all'inizio non ha funzionato per me. Non sono sicuro del perché, forse sto usando Chrome e una versione diversa di node. Dopo aver apportato alcune piccole modifiche, ora funziona per me.

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

Nel caso in cui qualcuno affronti un problema simile al mio, questo potrebbe essere utile.


Notare app.all vs app.get. È richiesta OPZIONI non OTTENERE
Shimon Doodkin

Questo funziona per me (sto recuperando oggetti usando Backbone). Sto cercando di capire se funzionerà in IE 8 ... sembra che dovrebbe, ma non so se è richiesto qualcosa di speciale per questa cosa "XDomainRequest" ... developer.mozilla.org/en- US / docs / HTTP /…
Adam Loving,

ALCUNE INFORMAZIONI PER FUTURI UTENTI: Sto reindirizzando il mio nome di dominio a un repository heroku, motivo per cui mi sono imbattuto in questo problema. Ad ogni modo, la prima risposta ha funzionato localmente ma non dopo averla inviata a heroku. Tuttavia questa risposta ha funzionato dopo aver spinto a heroku.
Kris Hollenbeck

@KrisHollenbeck Questo non funziona per me su heroku, hai fatto qualcos'altro?
Ben Craig

@ BenCraig, No, ma in realtà ha smesso di funzionare per me dopo il primo tentativo. Quindi in realtà ho ancora questo problema.
Kris Hollenbeck

11

Prova a questo cors npm modules.

var cors = require('cors')

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

Questo modulo fornisce molte funzionalità per mettere a punto l'impostazione di cors come la whitelist del dominio, l'abilitazione di cors per API specifiche ecc.


2

Io uso questo:

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

questo codice presuppone che i controller si trovino nella directory dei controller. ogni file in questa directory dovrebbe essere qualcosa del genere:

module.exports = function(app){

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

}

1

Consiglia di utilizzare il modulo cors express. Ciò ti consente di autorizzare i domini, consentire / limitare i domini in modo specifico per le rotte, ecc.,


0

È necessario impostare Access-Control-Allow-Credentials: true, se si desidera utilizzare "cookie" tramite "Credenziali"

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

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

});

Aggiungi questo codice nel tuo file index.js o server.js e modifica l'array di origine consentito in base alle tue esigenze.


-6

Un altro passaggio che dovevo fare era cambiare il mio URL da http://localhostahttp://127.0.0.0


A cosa ti riferisci?
Blunderfest
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.