Jak włączyć współużytkowanie zasobów między źródłami (CORS) w strukturze express.js na node.js.

101

Próbuję zbudować serwer WWW w node.js, który będzie obsługiwał skrypty międzydomenowe, jednocześnie dostarczając statyczne pliki z katalogu publicznego. Używam express.js i nie jestem pewien, jak zezwolić na wykonywanie skryptów międzydomenowych ( Access-Control-Allow-Origin: *).

Widziałem ten post , który nie był pomocny.

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);
Chłopak
źródło
Zwróć uwagę na app.all i app.get. To jest OPCJE, które nie są dostępne
Shimon Doodkin
zobacz lokalny serwer sieciowy, aby zapoznać się z przykładem prostego węzła, statycznego serwera WWW, który obsługuje CORS
Lloyd
Aby uzyskać więcej informacji, zobacz enable-cors.org/server_apache.html
Mostafa,
"Access-Control-Allow-Origin", "*"sprawia, że ​​Twój interfejs API jest interesujący dla aplikacji phishingowych. Rozważ zezwolenie tylko na znane źródła.
Martin Schneider

Odpowiedzi:

159

Zobacz przykład z enable-cors.org :

W aplikacji ExpressJS na node.js wykonaj następujące czynności ze swoimi trasami:

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

Pierwsze wywołanie ( app.all) należy wykonać przed wszystkimi innymi trasami w Twojej aplikacji (lub przynajmniej tymi, dla których chcesz włączyć mechanizm CORS).

[Edytować]

Jeśli chcesz, aby nagłówki pojawiały się również dla plików statycznych, spróbuj tego (upewnij się, że jest to przed wywołaniem 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();
});

Przetestowałem to z twoim kodem i uzyskałem nagłówki zasobów z publickatalogu:

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

Możesz oczywiście spakować funkcję w moduł, abyś mógł zrobić coś takiego

// 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
źródło
Hej, dzięki za twoją odpowiedź. Zrobiłem to, co zasugerowałeś (pierwsza część, ale nadal nie widzę niczego innego w nagłówkach żądań). Załączam mój obecny kod powyżej. czy możesz wyjaśnić, jak mogę zintegrować resztę twojego rozwiązania z tym?
Guy,
1
Dziwię się, że skoro jesteś useing app.routerwcześniej express.static, że nie modyfikować nagłówki dla plików statycznych; w każdym razie zaktualizowałem odpowiedź, aby działała.
Michelle Tilley,
Dzięki! Widzę, że masz rację. Zasoby pobierane z serwera mają żądane nagłówki. Mogłem nie mieć jasności co do mojego prawdziwego problemu. Próbuję wykonać wywołanie API do serwera zewnętrznego za pomocą polecenia get. i tam pojawia się błąd: XMLHttpRequest nie może załadować SOMEURL.com . Origin localhost: 8888 nie jest dozwolony przez Access-Control-Allow-Origin.
Guy,
Mogę być nieporozumieniem. Czy kontrolujesz serwer w witrynie SOMEURL.com?
Michelle Tilley,
Przepraszam, że teraz całkowicie rozumiem twoją odpowiedź. Wielkie dzięki. Doceniam twoją pomoc :)
Guy
58

Po rozwiązaniu @Michelle Tilley najwyraźniej na początku nie zadziałało. Nie wiem dlaczego, może używam Chrome i innej wersji node. Po wprowadzeniu kilku drobnych poprawek, teraz działa dla mnie.

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

W przypadku, gdy ktoś ma podobny problem jak mój, może to być pomocne.

TonyTakeshi
źródło
Zwróć uwagę na app.all i app.get. Żądanie OPCJI nie
POBIERAJ
To działa dla mnie (pobieram obiekty za pomocą Backbone). Próbuję dowiedzieć się, czy to zadziała w IE 8 ... wydaje się, że powinno, ale nie wiem, czy do tej rzeczy „XDomainRequest” jest wymagane coś specjalnego ... developer.mozilla.org/en- US / docs / HTTP /…
Adam Loving
KILKA INFORMACJI DLA PRZYSZŁYCH UŻYTKOWNIKÓW: Przekierowuję nazwę mojej domeny do repozytorium heroku, dlatego napotkałem ten problem. W każdym razie pierwsza odpowiedź zadziałała lokalnie, ale nie po przesłaniu jej do heroku. Jednak ta odpowiedź zadziałała po przejściu do heroku.
Kris Hollenbeck
@KrisHollenbeck To nie działa dla mnie na heroku, czy zrobiłeś coś jeszcze?
Ben Craig,
@BenCraig, Nie, ale tak naprawdę przestał działać po pierwszej próbie. Tak więc nadal mam ten problem.
Kris Hollenbeck,
11

Spróbuj tego cors npm moduły.

var cors = require('cors')

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

Ten moduł zapewnia wiele funkcji umożliwiających precyzyjne dostrojenie ustawień procesorów, takich jak biała lista domen, włączanie sterowników dla określonych interfejsów API itp.

Zahid Rahman
źródło
2

Używam tego:

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

ten kod zakłada, że ​​kontrolery znajdują się w katalogu kontrolerów. każdy plik w tym katalogu powinien wyglądać mniej więcej tak:

module.exports = function(app){

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

}
Elmer
źródło
1

Polecam korzystanie z modułu cors express. Pozwala to na umieszczanie domen na białej liście, zezwalanie / ograniczanie domen specjalnie do tras itp.,

Jerome Anthony
źródło
0

Musisz ustawić Access-Control-Allow-Credentials: true, jeśli chcesz używać „cookie” poprzez „Poświadczenia”

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();
});
dukegod
źródło
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();

});

Dodaj ten kod do pliku index.js lub server.js i zmień dozwoloną tablicę pochodzenia zgodnie z wymaganiami.

Atyos
źródło
-6

Dodatkowym krokiem, który musiałem wykonać, było przełączenie adresu URL z http://localhostnahttp://127.0.0.0

user3795430
źródło
Co pan myśli?
Blunderfest