Firefox 中的 Websocket 无法处理多个 HTTPS 页面
Posted
技术标签:
【中文标题】Firefox 中的 Websocket 无法处理多个 HTTPS 页面【英文标题】:Websockets in Firefox not working with several HTTPS pages 【发布时间】:2014-08-18 17:46:11 【问题描述】:我有一个 websocket 客户端-服务器应用程序。这是客户的简化代码:
const HOST = "wss://localhost:8000";
const SUB_PROTOCOL= "sub-protocol";
var websocket = new WebSocket(HOST, SUB_PROTOCOL);
websocket.onopen = function(evt) ... ;
websocket.onclose = function(evt) ... ;
websocket.onerror = function(evt) ... ;
websocket.onmessage = function(evt) ... ;
这里是服务器:
const PORT = 8000;
const SUBPROTOCOL = 'sub-protocol';
var WebSocketServer = require('websocket').server;
var https = require('https');
var fs = require('fs');
// Private key and certification (self-signed for now)
var options =
key: fs.readFileSync('cert/server.key'),
cert: fs.readFileSync('cert/server.crt')
;
var server = https.createServer(options, function(request, response)
console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
response.writeHead(404);
response.end();
);
// bind server object to listen to PORT number
server.listen(PORT, function()
console.log((new Date()) + ' Server is listening on port ' + PORT);
);
wsServer = new WebSocketServer(
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
);
function originIsAllowed(origin)
// put logic here to detect whether the specified origin is allowed.
return true;
// If autoAcceptConnections is set to false, a request event will be emitted
// by the server whenever a new WebSocket request is made
wsServer.on('request', function(request)
if (!originIsAllowed(request.origin))
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
// accepts connection and return socket for this connection
var connection = request.accept(SUB_PROTOCOL, request.origin);
console.log((new Date()) + ' Connection accepted.');
// when message is received
connection.on('message', function(message)
// echo
connection.send(connection, message.utf8Data);
);
connection.on('close', function(reasonCode, description)
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
);
);
即使使用一些 HTTPS 页面(在 Twitter、mail.ru 上测试),客户端和服务器都可以正常工作。但由于某些原因,例如 Facebook 或 GitHub 上没有。
在 javascript 控制台中我得到这个:
Exception message: "", result: 2153644038, name: "", filename: "", lineNumber: 0, columnNumber: 0, inner: null, data: null
然后是巨大的堆栈跟踪:粘贴它here
最后:
Content Security Policy: The page's settings blocked the loading of a resource at wss://localhost:8000/ ("connect-src https://github.com:443 https://ghconduit.com:25035 https://live.github.com:443 https://uploads.github.com:443 https://s3.amazonaws.com:443").
我看不出这些页面与有效的页面有何不同。我还想指出,这些页面可以在 Chrome 中使用。
(在 Firefox 31 中测试)
【问题讨论】:
【参考方案1】:WebSocket 连接失败的页面有一个 Content-Security-Policy
标头,其中 connect-src
指令设置为仅允许连接到一组列入白名单的域。这意味着从该页面到任何未列入白名单的域的所有连接都将失败。
不清楚您是如何运行此代码的。 Chrome 似乎有可能允许扩展绕过该标头限制,而 Firefox 不允许,或类似的东西。
【讨论】:
是的,客户端的代码是作为内容脚本在 firefox/chrome 插件中运行的库的一部分。所以我想这与此无关?如果我可以破坏内容安全策略,就没有理由拥有它,对吧。还好,这只是一种实验方法,所以如果它死了,我可以关闭它,以免为时已晚。 @dakov 我找不到让 Firefox 在 Content-Security-Policy 标头和插件方面表现得像 Chrome 的方法。看起来像一个死胡同。以上是关于Firefox 中的 Websocket 无法处理多个 HTTPS 页面的主要内容,如果未能解决你的问题,请参考以下文章
firefox使用 websocket 报无法建立到 ws://服务器的连接错误,ie和chrom都可以,求解释。。
Ubuntu 13.10 中的 websocket 连接失败