如何让自定义节点服务器上的socket.io接受CORS请求



我在socket.io服务器上出现CORS错误:

Access to XMLHttpRequest at 'http://dev.learnintouch.com:9001/socket.io/?EIO=3&transport=polling&t=NbAVesU' from origin 'http://dev.learnintouch.com:83' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我确实使用cors属性:

module.exports.io = socketio(httpsServer, {
cors: {
origin: 'http://dev.learnintouch.com:83'
}
});

我还尝试了*属性:

module.exports.io = socketio(httpsServer, {
cors: {
origin: '*',
methods: [
'GET',
'POST'
],
allowedHeaders: [],
credentials: true
}
});

但是误差是完全相同的。

以下是日志的内容:

The NodeJS HTTP server [port: 9001] is listening...
{
redis: { hostname: 'redis', port: 6379 },
socketio: { port: 9001, sslport: 9002 },
ssl: {
path: '/usr/local/learnintouch/letsencrypt/',
key: 'current-privkey.pem',
certificate: 'current-cert.pem',
chain: 'current-fullchain.pem'
}
}
The virtual host DOESN'T have an SSL private key
Configuring the server for HTTP
The HTTP server is used by the healthcheck even if the socket is served on the HTTPS server
Server {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
_nsps: Map {
'/' => Namespace {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
sockets: Map {},
_fns: [],
_ids: 0,
server: [Circular],
name: '/',
adapter: [Adapter],
[Symbol(kCapture)]: false
}
},
parentNsps: Map {},
_path: '/socket.io',
clientPathRegex: /^/socket.io/socket.io(.min|.msgpack.min)?.js(.map)?$/,
_connectTimeout: 45000,
_serveClient: true,
_parser: {
protocol: 5,
PacketType: {
'0': 'CONNECT',
'1': 'DISCONNECT',
'2': 'EVENT',
'3': 'ACK',
'4': 'CONNECT_ERROR',
'5': 'BINARY_EVENT',
'6': 'BINARY_ACK',
CONNECT: 0,
DISCONNECT: 1,
EVENT: 2,
ACK: 3,
CONNECT_ERROR: 4,
BINARY_EVENT: 5,
BINARY_ACK: 6
},
Encoder: [Function: Encoder],
Decoder: [Function: Decoder]
},
encoder: Encoder {},
_adapter: [Function: Adapter],
sockets: Namespace {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
sockets: Map {},
_fns: [],
_ids: 0,
server: [Circular],
name: '/',
adapter: Adapter {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
nsp: [Circular],
rooms: Map {},
sids: Map {},
encoder: Encoder {},
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
},
opts: { cors: { origin: 'http://dev.learnintouch.com:83' } },
[Symbol(kCapture)]: false
}

我的socket.io.min.js版本是:

/*!
* Socket.IO v4.0.1
* (c) 2014-2021 Guillermo Rauch
* Released under the MIT License.
*/

npm安装了cors并添加了require,但我不确定是否需要。

有关更多信息,服务器实现:

var http = require('http');
var https = require('https');
var cors = require('cors');
var connect = require('connect');
var cookie = require('cookie');
var path = require('path');
var fs = require('fs');
var redis = require('redis');
var ioredis = require('socket.io-redis');
var socketio = require('socket.io');
var utils = require('./utils.js');
var config = require('./config');
var sslKey = '';
var sslCertificate = '';
var sslChain = '';
if (fs.existsSync(config.ssl.path + config.ssl.key)) {
sslKey = fs.readFileSync(path.resolve(config.ssl.path + config.ssl.key));
sslCertificate = fs.readFileSync(path.resolve(config.ssl.path + config.ssl.certificate));
sslChain = fs.readFileSync(path.resolve(config.ssl.path + config.ssl.chain));
console.log("The virtual host HAS an SSL private key");
} else {
console.log("The virtual host DOESN'T have an SSL private key");
}
console.log("Configuring the server for HTTP");
console.log("The HTTP server is used by the healthcheck even if the socket is served on the HTTPS server");
var httpServer = http.createServer(utils.httpHandler);
httpServer.listen(config.socketio.port, function() {
console.log('The NodeJS HTTP server [port: ' + config.socketio.port + '] is listening...');
});
if (sslKey) {
console.log("Configuring the server for HTTPS");
var options = {
key: sslKey,
cert: sslCertificate,
ca: sslChain,
requestCert: false,
rejectUnauthorized: false
};
var httpsServer = https.createServer(options, utils.httpHandler);
httpsServer.listen(config.socketio.sslport, function() {
console.log('The NodeJS HTTPS server [port: ' + config.socketio.sslport + '] is listening...');
});
}
module.exports.io = socketio(httpsServer, {
cors: {
origin: '*',
methods: [
'GET',
'POST'
],
allowedHeaders: [],
credentials: true
}
});
console.log(module.exports.io);
module.exports.io.adapter(ioredis({ host: config.redis.hostname, port: config.redis.port }));
var redisClient = redis.createClient(config.redis.port, config.redis.hostname);
module.exports.io.use(function (socket, handler) {
if (socket.request.headers.cookie) {
socket.request.cookies = cookie.parse(decodeURIComponent(socket.request.headers.cookie));
socket.request.sessionID = socket.request.cookies['PHPSESSID'];
socket.request.socketSessionId = socket.request.cookies['socketSessionId'];
console.log("Authorization attempt with sessionID: " + socket.request.sessionID + " and socketSessionId: " + socket.request.socketSessionId);
redisClient.get("PHPREDIS_SESSION:" + socket.request.sessionID, function (error, reply) {
if (error) {
console.log("The redis client had an error: " + error);
return handler(new Error('The connection was refused because the redis client had an error.'));
} else if (!reply) {
console.log('The connection was refused because the redis client did not find the sessionID.');
return handler(new Error('The connection was refused because the redis client did not find the sessionID.'));
} else {
var redisSocketSessionId = utils.getRedisValue(reply, "socketSessionId");
if ('undefined' == typeof socket.request.socketSessionId || redisSocketSessionId != socket.request.socketSessionId) {
console.log('The connection was refused because the socketSessionId was invalid.');
return handler(new Error('The connection was refused because the socketSessionId was invalid.'));
} else {
console.log('The connection was granted.');
handler();
}
}
});
} else {
console.log('The connection was refused because no cookie was transmitted.');
return handler(new Error('The connection was refused because no cookie was transmitted.'));
}
});

更新:utils.js文件:

var formidable = require('formidable');
Array.prototype.contains = function(k, callback) {
var self = this;
return (function check(i) {
if (i >= self.length) {
return callback(false);
}
if (self[i] === k) {
return callback(true);
}
return process.nextTick(check.bind(null, i+1));
}(0));
};
module.exports.isEmpty = function(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
module.exports.getRedisValue = function(data, name) {
var redisBits = data.split(";");
for (var i in redisBits) {
if (redisBits.hasOwnProperty(i)) {
if (redisBits[i].substring(0, name.length) == name) {
var value = redisBits[i].split("|")[1].split(":")[2].replace(""", "").replace(""", "");
return(value);
}
}
}
};
// Handle http requests sent to the Node.js server
module.exports.httpHandler = function(req, res) {
switch(req.url) {
case '/ping':
if (req.method == 'GET') {
//        console.log("Received a [200] " + req.method + " to " + req.url);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('');
}
break;
case '/push':
if (req.method == 'POST') {
//        console.log("Received a [200] " + req.method + " to " + req.url);
form = new formidable.IncomingForm();
form.parse(req, function(e, fields, files) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('');
httpHandleServerPostRequest(fields);
});
}
break;
default:
send404(res);
};
};
send404 = function(res) {
res.writeHead(404);
res.write('404');
res.end();
};

我在HTTP服务器处理程序中添加了头,它解决了问题:

// Handle http requests sent to the Node.js server
module.exports.httpHandler = function(req, res, next) {
// Allow CORS
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
switch(req.url) {
case '/ping':
if (req.method == 'GET') {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('');
}
break;
case '/push':
if (req.method == 'POST') {
form = new formidable.IncomingForm();
form.parse(req, function(e, fields, files) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('');
httpHandleServerPostRequest(fields);
});
}
break;
default:
};
};

相关内容

  • 没有找到相关文章

最新更新