Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何让自定义节点服务器上的socket.io接受CORS请求?_Socket.io_Cors - Fatal编程技术网

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

如何让自定义节点服务器上的socket.io接受CORS请求?,socket.io,cors,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

我在
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:
  };
};

能否添加utils.js文件的代码?我想检查utils.httpHandler的内容。是的,您不需要require(“cors”)@Albert Thompson,但我确实需要
npm安装cors
?是的,您需要npm安装cors