我在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);
答案 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