Cách bật chia sẻ tài nguyên nguồn gốc chéo (CORS) trong khung express.js trên node.js


101

Tôi đang cố gắng xây dựng một máy chủ web trong node.js sẽ hỗ trợ tập lệnh tên miền chéo, trong khi vẫn cung cấp các tệp tĩnh từ một thư mục công khai. Tôi đang sử dụng express.js và không thực sự chắc chắn về cách cho phép viết mã miền chéo ( Access-Control-Allow-Origin: *).

Tôi đã thấy bài đăng này , mà tôi không thấy hữu ích.

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

Lưu ý app.all so với app.get. Đó là yêu cầu không OPTIONS GET
Shimon Doodkin

xem local-web-server để biết ví dụ về một nút đơn giản, máy chủ web tĩnh hỗ trợ CORS
Lloyd

xem enable-cors.org/server_apache.html để biết thêm thông tin
Mostafa vào

Câu trả lời:


159

Xem ví dụ từ enable-cors.org :

Trong ứng dụng ExpressJS của bạn trên node.js, hãy làm như sau với các tuyến đường của bạn:

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

Cuộc gọi đầu tiên ( app.all) phải được thực hiện trước tất cả các tuyến khác trong ứng dụng của bạn (hoặc ít nhất là những tuyến bạn muốn được kích hoạt CORS).

[Biên tập]

Nếu bạn muốn tiêu đề cũng hiển thị cho các tệp tĩnh, hãy thử điều này (đảm bảo nó trước khi gọi đến 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();
});

Tôi đã thử nghiệm điều này với mã của bạn và nhận tiêu đề về nội dung từ publicthư mục:

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

Tất nhiên, bạn có thể đóng gói chức năng thành một mô-đun để bạn có thể làm những việc như

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

Này, cảm ơn vì phản hồi của bạn. Tôi đã làm những gì bạn đề xuất (phần đầu tiên, nhưng vẫn không thấy bất kỳ khác biệt nào trong tiêu đề yêu cầu) Tôi đã đính kèm mã hiện tại của mình ở trên. bạn có thể giải thích cách tôi có thể tích hợp phần còn lại của giải pháp của bạn vào đó không?
Guy

1
Tôi ngạc nhiên rằng, kể từ khi bạn đang useing app.routertrước express.staticrằng nó không sửa đổi các tiêu đề cho các tập tin tĩnh; trong mọi trường hợp, tôi đã cập nhật câu trả lời của mình để nó hoạt động.
Michelle Tilley

Cảm ơn! Tôi thấy rằng bạn đã đúng. Nội dung được lấy từ máy chủ có tiêu đề được yêu cầu. Tôi có thể đã không rõ ràng về vấn đề thực sự của tôi. Tôi đang cố thực hiện lệnh gọi API tới máy chủ bên ngoài bằng lệnh get. và đó là nơi tôi gặp lỗi: XMLHttpRequest không thể tải SOMEURL.com . Nguồn gốc localhost: 8888 không được phép bởi Access-Control-Allow-Origin.
Guy

Tôi có thể đang hiểu lầm. Bạn có đang kiểm soát máy chủ tại SOMEURL.com không?
Michelle Tilley

Xin lỗi tôi hoàn toàn hiểu câu trả lời của bạn bây giờ. Cảm ơn rất nhiều. Tôi đánh giá cao sự giúp đỡ của bạn :)
Guy

58

Theo giải pháp @Michelle Tilley, dường như lúc đầu nó không hiệu quả với tôi. Không chắc tại sao, có thể tôi đang sử dụng chrome và phiên bản khác của nút. Sau khi thực hiện một số chỉnh sửa nhỏ, nó đang hoạt động đối với tôi bây giờ.

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

Trong trường hợp ai đó gặp phải vấn đề tương tự như tôi, điều này có thể hữu ích.


Lưu ý app.all so với app.get. Đó là yêu cầu không OPTIONS GET
Shimon Doodkin

Điều này phù hợp với tôi (tôi đang tìm nạp các đối tượng bằng cách sử dụng Backbone). Tôi đang cố gắng tìm hiểu xem nó có hoạt động trong IE 8 hay không ... có vẻ như vậy, nhưng tôi không biết liệu có yêu cầu gì đặc biệt cho thứ "XDomainRequest" này không ... developer.mozilla.org/en- US / docs / HTTP /…
Adam Loving

MỘT SỐ THÔNG TIN CHO NGƯỜI DÙNG TRONG TƯƠNG LAI: Tôi đang chuyển hướng tên miền của mình sang repo heroku, đó là lý do tại sao tôi gặp phải vấn đề này. Dù sao, câu trả lời đầu tiên hoạt động cục bộ nhưng không phải sau khi tôi đẩy nó sang heroku. Tuy nhiên câu trả lời này đã có tác dụng sau khi đẩy đến heroku.
Kris Hollenbeck

@KrisHollenbeck Điều này không hiệu quả với tôi trên heroku, bạn có làm gì khác không?
Ben Craig,

@BenCraig, Không, nhưng nó thực sự ngừng hoạt động đối với tôi sau lần thử đầu tiên. Vì vậy, tôi thực sự vẫn gặp vấn đề này.
Kris Hollenbeck

11

Cố gắng này CORS NPM mô-đun.

var cors = require('cors')

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

Mô-đun này cung cấp nhiều tính năng để tinh chỉnh cài đặt cors chẳng hạn như danh sách miền cho phép, bật cors cho các apis cụ thể, v.v.


2

Tôi sử dụng cái này:

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

mã này giả định rằng bộ điều khiển của bạn nằm trong thư mục bộ điều khiển. mỗi tệp trong thư mục này phải giống như sau:

module.exports = function(app){

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

}

1

Khuyến nghị sử dụng mô-đun cors express. Điều này cho phép bạn đưa các miền vào danh sách trắng, cho phép / hạn chế miền cụ thể đối với các tuyến đường, v.v.


0

Bạn phải đặt Access-Control-Allow-Credentials: true, nếu bạn muốn sử dụng "cookie" qua "Thông tin đăng nhập"

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

});

Thêm mã này vào tệp index.js hoặc server.js của bạn và thay đổi mảng nguồn gốc được phép theo yêu cầu của bạn.


-6

Một bước bổ sung tôi cần phải mất là để chuyển đổi URL của tôi từ http://localhostđếnhttp://127.0.0.0


bạn đang đề cập gì tới?
Blunderfest
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.