簡體   English   中英

Node.js-Websocket在由Nginx反向代理提供服務時拒絕打開連接

[英]Node.js - Websocket refuses to open a connection when served by Nginx reverse proxy

目前,我正在嘗試建立一個簡單的聊天應用程序。 我正在使用total.js框架。 我的Node.js程序在[http]://127.0.0.1:8000 /上運行。 只要請求URI與加載頁面的HTML代碼中指定的確切URI匹配,這就有效。 例如,轉到[http]:// localhost:8000 / wil加載html頁面,但是[http]://127.0.0.1:8000將按預期工作時,所有功能都不起作用。

我在嘗試將Nginx設置為反向代理時發現了這一點,因此可以通過轉到[http]://127.0.0.1:80 /來實現。 這里將加載html頁面,但聊天功能不起作用。

此聊天應用程序是total.js示例的一部分。

這是創建websocket的index.html文件:

 <div class="mb5"> <button name="open">CONNECT</button> </div> <div> <button name="close" disabled="disabled">DISCONNECT</button> </div> <br /> <div> <input type="text" name="message" maxlength="200" style="width:500px" /> <button name="send" disabled="disabled">SEND</div> </div> <br /> <div> <textarea id="output" style="width:620px;height:300px" readonly="readonly"></textarea> </div> <br /> <div> <input type="text" value="" name="username" maxlength="20" style="width:200px" /> <button name="rename" disabled="disabled">RENAME</div> </div> <script type="text/javascript"> var socket = null; $(document).ready(function() { $('button').bind('click', function() { if (this.name === 'rename') { var value = $('input[name="username"]').val(); if (value.length > 0) socket.send(encodeURIComponent(JSON.stringify({ username: value }))); return; } if (this.name === 'send') { console.log('send'); send(); return; } if (this.name === 'open') { connect(); return; } console.log('disconnect'); disconnect(); }); }); function connect() { if (socket !== null) return; $('button[name="open"]').attr('disabled', true); $('button[name="close"],button[name="send"],button[name="rename"]').attr('disabled', false); socket = new WebSocket('ws://127.0.0.1:8000/'); socket.onopen = function() { console.log('open'); }; socket.onmessage = function(e) { var el = $('#output'); var m = JSON.parse(decodeURIComponent(e.data)).message; el.val(m + '\\n' + el.val()); }; socket.onclose = function(e) { // e.reason ==> total.js client.close('reason message'); $('button[name="open"]').attr('disabled', false); }; } function send() { var el = $('input[name="message"]'); var msg = el.val(); if (socket !== null && msg.length > 0) socket.send(encodeURIComponent(JSON.stringify({ message: msg }))); el.val(''); } function disconnect() { if (socket === null) return; $('button[name="close"],button[name="send"],button[name="rename"]').attr('disabled', true); $('button[name="open"]').attr('disabled', false); socket.close(); socket = null; } </script> 

這聽起來像同源保護。

除非您的socket.io服務器支持COR並允許從跨域訪問,否則當從localhost:8000加載網頁時,瀏覽器將不允許連接到127.0.0.1:8000 ,反之亦然。 您連接的域必須匹配網頁的域,除非您的服務器支持CORS並明確允許跨源連接。

而且,即使localhost:8000127.0.0.1:8000實際上可能是同一台服務器,瀏覽器也不會允許它。

解決特定問題的通常方法是僅使用Javascript中的window.location獲取當前頁面URL中的主機名形式,並使用該主機名構造URL,以確保使用相同的主機名。頁面URL中的主機名。

例如:

socket = new WebSocket('ws://' + window.location.host + '/');

我認為這不用說你的nginx代理也必須專門配置為支持webSocket連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM