node express和socket.io中的CORS配置没有'Access-Control-Allow-Origin'

时间:2018-06-01 17:06:50

标签: node.js express socket.io cors

我在Heroku上托管了我的API,在其他服务器上托管了Angular webAPP。将socket.io集成到API时遇到问题,我对api的调用不起作用,我得到错误503,这是由CORS的一些错误配置引起的?

app.js(在heroku服务器中托管的Node.js / Express)

var express = require('express');
var app = express();

var port = process.env.PORT || 8080;
//var port = 3000;

// Notification Real Time 
// http://4dev.tech/2017/12/tutorial-creating-a-realtime-notification-system-in-angular-and-nodejs/
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
io.set("origins", "*:*");

var socket_port = process.env.PORT || 8000;
server.listen(socket_port);
//server.listen(8000);

io.on('connection', function(socket) {
  socket.on('create notification', function( data ) {
    socket.broadcast.emit('new notification', data);
  });
});

/* ... more code ...*/

app.listen(port, ()=> {
    console.log('Node/Express: \x1b[32m%s\x1b[0m', 'online - port: '+ port);
});

在Chrome控制台中显示错误:

  

选项https://myapp-backend.herokuapp.com/login 503(服务   不可用)无法加载https://myapp-backend.herokuapp.com/login:   对预检请求的响应未通过访问控制检查:否   请求中存在“Access-Control-Allow-Origin”标头   资源。因此不允许来源“http://my-domain.com”   访问。响应具有HTTP状态代码503

修改

如果设置server.listen(8000);,则会收到404错误:

  

获取https://myapp-backend.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MEyiNar   404(未找到)

跟随:

  

无法加载   https://myapp-backend.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MEyiNar:   响应中“Access-Control-Allow-Origin”标头的值   请求的凭据模式为时,不能是通配符'*'   '包括'。因此,不允许原点“http://my-domain”访问。   XMLHttpRequest发起的请求的凭证模式是   由withCredentials属性控制。

更新

使用此配置效果很好,端口出现问题

// Notification Real Time 
// http://4dev.tech/2017/12/tutorial-creating-a-realtime-notification-system-in-angular-and-nodejs/
var io = require('socket.io')(server);
// io.set("origins", "*:*");

io.on('connection', function(socket) {
  socket.on('create notification', function( data ) {
    socket.broadcast.emit('new notification', data);
  });
});
// var socket_port = process.env.PORT || 8080;
// server.listen(socket_port);
//server.listen(8000);

2 个答案:

答案 0 :(得分:0)

浏览器使用OPTIONS方法检查几个CROS。 (例如允许哪些方法)

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

 // Add this
 if (req.method === 'OPTIONS') {

      res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, OPTIONS');
      res.header('Access-Control-Max-Age', 120);
      return res.status(200).json({});
  }

  next();

});

Checkout MDN for full details of OPTIONS method.

修改 我刚注意到,这是另一个错误,这个应用程序在本地使用两个不同的端口,但在Heroku中你只能得到一个端口。

编辑2: 端口问题已由用户&这个答案是对这个问题的实际答案。

答案 1 :(得分:-1)

任何可能对用户数据产生影响的HTTP方法都将首先通过OPTIONS方法发送HTTP请求。您的跨域域应该发送自定义标头,接受交叉源请求的服务器应该接受该标头。

无论您的实际请求是什么,在OPTIONS请求成功之前都不会提交。

例如,http://my-domain.com可以首先将这些标头添加到请求中:

Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-CUSTOM-HEADER, Content-Type

https://myapp-backend.herokuapp.com/login应该有这个使用规范:

Access-Control-Allow-Origin: http://my-domain
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: X-CUSTOM-HEADER, Content-Type
Access-Control-Max-Age: 86400

在此处了解预检请求:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS