【问题标题】:Will linking external JS from Node.js via Apache allow me to use SSE "bypassing" the Apache proxy?通过 Apache 从 Node.js 链接外部 JS 是否允许我使用 SSE“绕过”Apache 代理?
【发布时间】:2014-10-06 10:27:47
【问题描述】:

我想使用 Apache 提供(大部分)静态内容,因为这是我喜欢的,但我希望 Node.js 处理服务器发送的事件。但是,它们都在同一台机器上。

问题是,如果我像这样在我的 Apache 服务器中设置我的 sseListener.html:

sseListener.html (Apache)

<body>
    <div id="test"></div>

    <script type="text/javascript">
        var source = new EventSource("http://localhost:8888/test2js.js");
        var test = document.getElementById("test");

        source.addEventListener("message", function(e){
            test.innerHTML = "";
            test.innerHTML = JSON.parse(e.data).test;
        }, false);

        source.onopen = function(){
            console.log("open: ");
        }

        source.onclose = function(){
            console.log("close: ");
        }

        source.onerror = function(){
            console.log("error: ");
        }
    </script>
</body>

我在控制台中收到此错误:

EventSource cannot load http://localhost:8888/test2js.js. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.    

以下是我的 Node 服务器,上面的脚本试图与之通信:

test2js.js(节点)

var http = require("http");
var date = new Date();

  function onRequest(request, response) {
    console.log("Request received.");
    response.writeHead(200, {"Content-Type": "text/event-stream"});
    response.write("{ \"id\": \"" + date + "\", \"data\": \"test\"}");
    response.end();
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");

我意识到这是因为我正在尝试使用通过 Apache 提供服务的 EventSource 客户端与 Node 托管的服务器进行通信,就像 Ajax 调用因跨域问题而失败一样。

在互联网上阅读,我知道我可以设置从 Apache 到 Node 的代理,但后来我也读到这违背了我让 Node 处理并发连接的目的 - Apache 将设置线程以与它进行通信节点而不是根本不必这样做。

我如何理解这个过程的工作:

但是,我不喜欢请求必须先路由到 Apache,然后再路由到节点。我希望请求直接发送到 Node。

我意识到有两种“明显”的方法可以做到这一点:

  1. 在 Node 中设置我的整个应用程序 -> 这对我来说不是一个好的选择,因为我对 PHP 更熟悉,而且我的 JavaScript 能力不如我的 PHP
  2. 只需通过 Apache 处理 SSE -> 我也不想这样做。我运行的服务器实际上并不是我一个人,我只是将我的应用程序安装在它上面并“借用”空间,所以我想实现一些尽可能轻量级的东西。

所以考虑到这个问题,我想出了一个我不确定是否可行的解决方案,但我也不知道如何实现它:让 Apache 获取客户端 js 代码并将其链接到 sseListener.html,像这样:

<body>
    <div id="test"></div>
    <script type="text/javascript" src="path/to/node/file/system/sseClient.js"></script>
</body>

猜测的方式会起作用,然后,就像:

换句话说:将 client.js 文件(带有 EventSource)保存在 Node 目录中,使用 Apache 抓取该文件并以某种方式附加它,然后将其提供给客户端。所以当客户端发出请求时,它会直接发送到 Node 而不是 Apache。

所以我的问题:

  1. 这可能吗?
  2. 如果是这样,我该如何实施?
  3. 否则,是否有任何其他方法可以通过 Apache 向客户端提供文件,但将 SSE 端偏移到 Node,没有让 Apache 也必须处理连接?

从字面上看,我希望我的 Node 服务器做的就是将数据推送到 Apache 将生成的客户端。它根本不会做任何复杂的事情。我只是想利用它的并发连接能力来制作一个更高效的应用程序。

【问题讨论】:

    标签: php node.js apache reverse-proxy server-sent-events


    【解决方案1】:

    我认为代理对您的目标来说是个坏主意。试试这个:

        var source = new EventSource("http://localhost:8888/test2js.js");
        var test = document.getElementById("test");
    
        source.onmessage = function(e){
            test.innerHTML = "";
            var data = JSON.parse(e.data);
            test.innerHTML = data.test + data.date;
        };
    

    在你的 test2js.js 中:

      function onRequest(request, response) {
      console.log("Request received.");
      response.writeHead(200, {"Content-Type": "text/event-stream",
                               "Cache-Control": "no-cache",
                                "Access-Control-Allow-Origin": "*"
                         });
      response.write("data:{\"date\":"+date+",\"test\":\"some value\"}\n\n");
      response.end();
      }
    

    【讨论】:

    • 嗨,谢谢。但是当我尝试你的代码时,它仍然给了我同样的错误:EventSource cannot load http://localhost:8888/test2js.js. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
    • 呃,不,抱歉,我不再看到那个错误了。我看到了我可以处理的“Uncaught SyntaxError: Unexpected token M”。我实际上是在启动一个不同的、错误的服务器。谢谢!
    猜你喜欢
    • 2011-11-03
    • 2020-05-27
    • 2011-04-09
    • 2013-09-03
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    相关资源
    最近更新 更多