我们有一个 html 站点和一个为该网站提供服务的 node.js 服务器。网站和服务器使用 socke.io 交换数据。我们在文档中发现了这一点:
origins 默认为 *:*
允许连接到 Socket.IO 服务器的源。
我们的 html.site 在http://questionexample.com/page1
. 只有这个站点可以连接到我们的服务器。(但每个人都可以连接到那个网站。)我们如何设置起源?
我们有一个 html 站点和一个为该网站提供服务的 node.js 服务器。网站和服务器使用 socke.io 交换数据。我们在文档中发现了这一点:
origins 默认为 *:*
允许连接到 Socket.IO 服务器的源。
我们的 html.site 在http://questionexample.com/page1
. 只有这个站点可以连接到我们的服务器。(但每个人都可以连接到那个网站。)我们如何设置起源?
如果您深入研究 Socket.io 源代码,您会发现以下几行:
var origin = request.headers.origin || request.headers.referer
, origins = this.get('origins');
...
var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
~origins.indexOf(parts.hostname + ':' + parts.port) ||
~origins.indexOf(parts.hostname + ':*') ||
~origins.indexOf('*:' + parts.port);
如您所见,Socket.io 获取来自客户端的来源(或引用者),检索域名和端口,并与origins
您指定的选项进行比较。
所以有效值origins
是(*
意味着“任何”):
testsite.com:80
http://testsite.com:80
http://*:8080
*:8080
testsite.com:* http://someotherdomain.com:8080
(多个原点以空格分隔)testsite.com:*/somepath
(socket.io 会忽略 /somepath)*:*
这些是无效的(因为没有端口号):
testsite.com
http://testsite.com
http://testsite.com/somepath
另请注意,如果您指定sub.testsite.com
为 origins 值,testsite.com
则将是有效的origin。
我有过类似的问题。尝试在生产模式下运行节点NODE_ENV=production node app.js
。我有那个代码(正如这里推荐的那样):
io.configure('production', function(){
console.log("Server in production mode");
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // apply etag caching logic based on version number
io.enable('browser client gzip'); // the file
io.set('log level', 1); // logging
io.set('transports', [ // all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
io.set('origins', 'http://questionexample.com/page1:*');
});
并且 Node 在开发模式下运行,所以它根本无法工作。启用生产模式后一切正常。
我知道答案有点晚,但也许其他人会使用它
对于较新版本的socket.io
(直到当前,4.x.x
您需要将 CORS 源设置为服务器选项的一部分。
CORS 现在被拆分成它自己的module - 有关详细信息,请参阅自述文件。
默认配置是;
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
并限制在一个站点使用任何子域;
cors: {
origin: [/\.example\.com$/],
methods: ["GET", "POST"]
}
这是一个非常简单/基本的配置块,适合那些不使用 express 或原始 socket.io 引擎以外的任何东西的人;编辑:更新了socket.io
.
// Options for socket.io => 3.0.0
var options = {
allowUpgrades: true,
transports: [ 'polling', 'websocket' ],
pingTimeout: 9000,
pingInterval: 3000,
cookie: 'mycookie',
httpCompression: true,
cors: '*:*' <---- Allow any origin here [NOTE THE NAME CHANGE]
};
旧版本使用;
// Options for socket.io > 1.0.0
var options = {
allowUpgrades: true,
transports: [ 'polling', 'websocket' ],
pingTimeout: 9000,
pingInterval: 3000,
cookie: 'mycookie',
httpCompression: true,
origins: '*:*' <---- Allow any origin here
};
io = require('socket.io')(8010, options);
您可以使用您网站的网址在服务器端执行类似操作
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
我认为io.set('origins', http://questionexample.com/page1)
应该这样做