问题
I have my API hosted on Heroku and the Angular webAPP in other server. I have a problem when integrating socket.io to the API, my calls to the api do not work and I get error 503, caused by some bad configuration of the CORS?
app.js (Node.js/Express hosted in heroku server)
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);
});
In the chrome console shows the error:
OPTIONS https://myapp-backend.herokuapp.com/login 503 (Service Unavailable) Failed to load https://myapp-backend.herokuapp.com/login: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://my-domain.com' is therefore not allowed access. The response had HTTP status code 503
EDIT
If set server.listen(8000);
get 404 error:
GET https://myapp-backend.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MEyiNar 404 (Not Found)
follow by:
Failed to load https://myapp-backend.herokuapp.com/socket.io/?EIO=3&transport=polling&t=MEyiNar: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://my-domain' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
UPDATE
It works great with this configuration, there was a problem with the ports
// 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);
回答1:
Browser uses OPTIONS
method check few CROS. (Such as which methods are allowed)
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.
EDIT: I just noticed, here is another error that this app uses two different port in locally but in Heroku you'll get only one port.
EDIT 2: Port issue has been fixed by user & this answer holds the actual answer of the question.
回答2:
Any HTTP method that might have implications on user data will first send an HTTP request by the OPTIONS method. Your cross-origin domain should send a custom header along and the server accepting the cross origin request should accept that header.
Whatever your actual request is will not be allowed to submit until the OPTIONS request is able to succeed.
For example, http://my-domain.com
could add these headers to the request first:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-CUSTOM-HEADER, Content-Type
And https://myapp-backend.herokuapp.com/login
should have this use specification:
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
Read about preflight requests here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
来源:https://stackoverflow.com/questions/50648137/cors-config-in-node-express-and-socket-io-no-access-control-allow-origin