Cara mengaktifkan berbagi sumber daya lintas sumber (CORS) dalam kerangka kerja express.js di node.js

101

Saya mencoba membangun server web di node.js yang akan mendukung skrip lintas domain, sambil tetap menyediakan file statis dari direktori publik. Saya menggunakan express.js dan tidak begitu yakin cara mengizinkan skrip lintas domain ( Access-Control-Allow-Origin: *).

Saya melihat posting ini , yang menurut saya tidak berguna.

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);
Orang
sumber
Perhatikan app.all vs app.get. Ini adalah PILIHAN meminta tidak DAPATKAN
Shimon Doodkin
lihat local-web-server untuk contoh node sederhana, server web statis yang mendukung CORS
Lloyd
lihat enable-cors.org/server_apache.html untuk info lebih lanjut
Mostafa

Jawaban:

159

Lihat contoh dari enable-cors.org :

Di aplikasi ExpressJS Anda di node.js, lakukan hal berikut dengan rute Anda:

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

Panggilan pertama ( app.all) harus dilakukan sebelum semua rute lain di aplikasi Anda (atau setidaknya yang Anda inginkan untuk mengaktifkan CORS).

[Sunting]

Jika Anda ingin header muncul untuk file statis juga, coba ini (pastikan sebelum panggilan ke 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();
});

Saya menguji ini dengan kode Anda, dan mendapatkan header pada aset dari publicdirektori:

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

Anda dapat, tentu saja, mengemas fungsi menjadi modul sehingga Anda dapat melakukan sesuatu seperti

// 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
sumber
Hei, terima kasih atas tanggapan Anda. Saya melakukan apa yang Anda sarankan (bagian pertama, tetapi masih tidak melihat perbedaan di header permintaan) Saya telah melampirkan kode saya saat ini di atas. dapatkah Anda menjelaskan bagaimana saya dapat mengintegrasikan sisa solusi Anda untuk itu?
Guy
1
Saya terkejut bahwa, karena Anda useing app.routersebelum express.staticbahwa hal itu tidak mengubah header untuk file statis; bagaimanapun juga, saya telah memperbarui jawaban saya agar berfungsi.
Michelle Tilley
Terima kasih! Saya melihat bahwa Anda benar. Aset yang didapat dari server dengan header yang diminta. Saya mungkin belum jelas tentang masalah saya yang sebenarnya. Saya mencoba membuat panggilan API ke server eksternal dengan perintah get. dan di situlah saya mendapatkan kesalahan: XMLHttpRequest tidak dapat memuat SOMEURL.com . Host lokal asal : 8888 tidak diizinkan oleh Access-Control-Allow-Origin.
Guy
Saya mungkin salah paham. Apakah Anda mengontrol server di SOMEURL.com?
Michelle Tilley
Maaf, saya sangat memahami jawaban Anda sekarang. Terima kasih banyak. Saya menghargai bantuan Anda :)
Guy
58

Mengikuti solusi @Michelle Tilley, tampaknya itu tidak berhasil untuk saya pada awalnya. Tidak yakin mengapa, mungkin saya menggunakan chrome dan versi node yang berbeda. Setelah melakukan beberapa perubahan kecil, ini berfungsi untuk saya sekarang.

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

Jika seseorang menghadapi masalah yang sama dengan saya, ini mungkin bisa membantu.

TonyTakeshi
sumber
Perhatikan app.all vs app.get. Ini adalah PILIHAN permintaan tidak DAPATKAN
Shimon Doodkin
Ini berfungsi untuk saya (saya mengambil objek menggunakan Backbone). Saya mencoba mencari tahu apakah itu akan berfungsi di IE 8 ... sepertinya seharusnya, tetapi saya tidak tahu apakah sesuatu yang khusus diperlukan untuk hal "XDomainRequest" ini ... developer.mozilla.org/en- US / docs / HTTP /…
Adam Loving
BEBERAPA INFO UNTUK PENGGUNA MASA DEPAN: Saya mengarahkan ulang nama domain saya ke repo heroku, itulah sebabnya saya mengalami masalah ini. Bagaimanapun, jawaban pertama bekerja secara lokal tetapi tidak setelah saya mendorongnya ke heroku. Namun jawaban ini berhasil setelah mendorong ke heroku.
Kris Hollenbeck
@KrisHolleck Ini tidak bekerja untuk saya di heroku, apakah Anda melakukan hal lain?
Ben Craig
@BenCraig, Tidak, tetapi sebenarnya berhenti berfungsi untuk saya setelah percobaan pertama. Jadi saya sebenarnya masih mengalami masalah ini juga.
Kris Hollenbeck
11

Cobalah untuk ini kor modul NPM.

var cors = require('cors')

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

Modul ini menyediakan banyak fitur untuk menyempurnakan pengaturan kors seperti daftar putih domain, mengaktifkan kors untuk apis tertentu, dll.

Zahid Rahman
sumber
2

Saya menggunakan ini:

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

kode ini mengasumsikan bahwa pengontrol Anda terletak di direktori pengontrol. setiap file di direktori ini harus seperti ini:

module.exports = function(app){

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

}
Elmer
sumber
1

Rekomendasikan untuk menggunakan modul cors express. Ini memungkinkan Anda untuk memasukkan domain ke dalam daftar putih, mengizinkan / membatasi domain secara khusus untuk rute, dll.,

Jerome Anthony
sumber
0

Anda harus mengatur Access-Control-Allow-Credentials: true, jika ingin menggunakan "cookie" melalui "Kredensial"

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

});

Tambahkan kode ini di file index.js atau server.js Anda dan ubah array asal yang diizinkan sesuai dengan kebutuhan Anda.

Atyos
sumber
-6

Satu langkah tambahan yang perlu saya lakukan adalah mengalihkan URL saya dari http://localhostmenjadihttp://127.0.0.0

pengguna3795430
sumber
Apa yang anda maksudkan?
Blunderfest