由于HTTPS是基于SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通讯加密,因此在HTTPS站点调用某些非SSL验证的资源时浏览器可能会阻止。好比使用ws://***调用websocket服务器或者引入相似http://***.js的js文件等都会报错。这里简述一下链接websocket服务器时的错误及解决方案。当使用ws://链接websocket服务器时会出现相似以下错误:nginx
Mixed Content: The page at '*****' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://*****'. This request has been blocked; this endpoint must be available over WSS.
(anonymous)
Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.web
若是浏览器不阻止,那在https站点下调用ssl资源才能够,面说一下解决方案:浏览器
方案一:假设HTTPS站点使用Nginx服务器,其余服务器也是相似的思路,能够用服务器代理ws服务,能够用nginx的WebSocket proxying,简述一下配置方案服务器
#首先将客户端请求websocket时的地址更改成wss://代理服务器url(代理服务器必须支持https) 例如 var ws = new WebSocket("wss://www.liminghulian.com/websocket"); #在代理服务器上的nginx配置文件中的server中增长以下配置项 location /websocket/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } #http中增长 upstream backend{ server websocket服务器的ip:端口; }
这样客户端请求的是wss://服务器,经过nginx的WebSocket proxying代理到实际不支持ssl的websocket服务器。websocket
方案二:直接为WebSocket服务器增长ssl证书,这样就能够直接经过wss://来请求服务器了,以swoole为例,其余服务器也是相似的思路,下面给出示例代码swoole
//使用SSL必须在编译swoole时加入--enable-openssl选项 $server = new Swoole\WebSocket\Server("0.0.0.0", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); $server->set( [ 'ssl_cert_file' => '证书', 'ssl_key_file' => '/usr/local/nginx/conf/cert/214517325220006.key', ] ); $server->on('open', function (Swoole\WebSocket\Server $server, $request) { echo "server: handshake success with fd{$request->fd}\n"; }); $server->on('message', function (Swoole\WebSocket\Server $server, $frame) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n"; $server->push($frame->fd, "this is server"); }); $server->on('close', function ($ser, $fd) { echo "client {$fd} closed\n"; }); $server->start();