我有一个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中测试)
答案 0 :(得分:1)
WebSocket连接失败的页面具有Content-Security-Policy
标头,connect-src
指令设置为仅允许连接到一组列入白名单的域。这意味着从该页面到任何非白名单域的所有连接都将失败。
目前还不清楚你是如何运行这段代码的。 Chrome可能允许扩展程序绕过该标头限制,而Firefox则不然,或者出现这种情况。