首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >由于Node.js和Angular,WebSocket代理失败。意外响应代码: 404

由于Node.js和Angular,WebSocket代理失败。意外响应代码: 404
EN

Stack Overflow用户
提问于 2018-05-31 01:22:40
回答 1查看 2.6K关注 0票数 2

我正在努力掌握代理websockets的最新进展。我有一些angular代码,我从一个针对echo.websocket.org测试websocket连接的教程中进行了修改。代码本身工作得很好。

<!DOCTYPE html>
<html>
   <meta charset = "utf-8" />
   <title>WebSocket Test</title>

   <script language = "javascript" type = "text/javascript">
      var wsUri = "ws://echo.websocket.org/";
      //var wsUri = "ws://localhost:8015"
      var output;
      var success = 0;
      var failure = 0;

      function init() {

        output = document.getElementById("output");
         output.innerHTML = "";
         testWebSocket();
         writeScore();

      }


      function testWebSocket() {
         websocket = new WebSocket(wsUri);

         websocket.onopen = function(evt) {
            onOpen(evt)
         };

         websocket.onclose = function(evt) {
            onClose(evt)
         };

         websocket.onmessage = function(evt) {
            onMessage(evt)
         };

         websocket.onerror = function(evt) {
            onError(evt)
         };
      }

      function onOpen(evt) {
         writeToScreen("CONNECTED");
         doSend("WebSocket rocks");
         success = success +1;
      }

     function onClose(evt) {
         writeToScreen("DISCONNECTED");
      }

      function onMessage(evt) {
         writeToScreen('<span style = "color: blue;">RESPONSE: ' + 
            evt.data+'</span>'); websocket.close();
      }

      function onError(evt) {
         writeToScreen('<span style = "color: red;">ERROR:</span> '
            + evt.data);
        failure = failure +1;
      } 

      function doSend(message) {
         writeToScreen("SENT: " + message); websocket.send(message);
      }

      function writeToScreen(message) {
         var pre = document.createElement("p"); 
         pre.style.wordWrap = "break-word"; 
         pre.innerHTML = message; 
         output.appendChild(pre);
      }

        function writeScore(){

        var pScore = document.createElement("p");
        pScore.style.wordWrap = "break-word";
        pScore.innerHTML = "Success   "+ success+ "   Failures   "+ failure;
        output.appendChild(pScore);

        }

      window.addEventListener("load", init, false);
   </script>

   <h2>WebSocket Test</h2>
   <div id = "output"></div>

</html>

按照https://github.com/nodejitsu/node-http-proxy#proxying-websockets的说明进行操作

我尝试用两种不同的方式设置一个简单的代理,通过修改angular代码中的wsUri变量来指向在此代码中创建的服务器,从而将angular页面的websocket请求转发到相同的echo.websocket.org连接。

///
// Setup our server to proxy standard HTTP requests
//

var httpProxy = require('http-proxy');
var http = require('http');

var proxy = new httpProxy.createProxyServer({
  target: {
    host: 'echo.websocket.org',
    port: 80
  }
});


var proxyServer = http.createServer(function (req, res) {
  proxy.web(req, res);
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
        console.log(socket);
        proxy.ws(req, socket, head);
});


proxyServer.listen(8015);

var test = httpProxy.createServer({
  target: 'ws://echo.websocket.org',
  ws: true
});

test.listen(8014);

不幸的是,代理请求(对于监听8014和8015端口的服务器)触发了angular websocket.onerror事件处理程序,为evt.data提供了一个不太有用的消息“undefined”。

更新:

当我尝试使用本地主机代理打开网页时,Chrome在开发人员工具中显示以下错误消息。

到'ws://localhost:8015/‘的

index.htm:29 WebSocket连接失败: WebSocket握手期间出错:意外响应代码: 404

Firefox在其"Web控制台“中显示以下内容

Firefox无法与位于ws://localhost:8015/的服务器建立连接。

但是,升级事件正在触发,因为我看到Node的控制台显示来自Node代码的console.log()行的套接字信息。这让我相信已经找到了本地主机服务器,这就是404错误的来源。我不确定它是否与查找代理(它触发了http升级事件)或代理的目标有关。

当浏览器和echo.websocket.org之间没有代理时,如何让Node代理angular websocket连接?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-02 04:30:23

Host: foo.com;它与在转发代理请求之前设置TLDR头相关。

基本上,Error during WebSocket handshake: Unexpected response code: 404意味着它实际上无法与给定的wsUri建立任何连接。

从可以看出,changeOrigin建议将true作为默认设置。

但是,在我们的示例中(默认情况下),它是false。因此,转发的请求在没有正确设置HTTP Host报头的情况下是无效的/畸形的。您可以尝试进一步调试,以查看真正的HTTP属性、标头等。

另外,

autoRewrite属性根据请求的主机/端口在(201/301/302/307/308)重定向上重写位置主机/端口。

尝试将以下属性作为createServer()参数添加:

autoRewrite: true,
changeOrigin: true,

因此,它变成了:

const test = httpProxy.createServer({
  target: 'ws://echo.websocket.org',
  ws: true,
  autoRewrite: true,
  changeOrigin: true,
});

test.listen(8014);

希望它能帮上忙!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50610344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档