我在企业环境中工作,发现了一个我无法解决的问题。
这与 EventSource
将 URL 参数从 HTTP
更改为 HTTPS
有关。
const url = 'http://localhost:8080'; // <-- using HTTP not HTTPS
new window.EventSource(url);
这导致浏览器抛出此错误:
GET https://localhost:8080 net::ERR_TUNNEL_CONNECTION_FAILED
我正在使用 HTTPS
在网站上进行开发,所以这可能是设计使然,它使用相同的协议(protocol)。有人遇到过这个问题或知道如何解决吗?
---更新---
看起来这是设计使然。在另一个 HTTPS 站点上尝试此操作时,我得到了这个:
混合内容:位于“https://...”的页面是通过 HTTPS 加载的,但请求了不安全的 EventSource 端点“http://localhost...”。此请求已被阻止;内容必须通过 HTTPS 提供。
问题仍然存在,我该如何解决这个问题?
最佳答案
事件源不会在 http 和 https 之间改变。您是否在使用适用于 Chrome 的 HTTPS Everywhere 插件或类似插件?
我认为您受到了同源策略的影响。这意味着 SSE 连接必须是同源的,这基本上意味着相同的主机名和域、相同的方案(即 http 或 https)和相同的端口。
您可以使用 CORS 来解决这个问题。在您的SSE 脚本顶部,您需要发回此 header :
Access-Control-Allow-Origin: *
这表示任何人都可以从任何地方连接并获取数据流。它必须在服务器脚本上完成,无法从客户端完成。 (按照设计:同源策略的全部意义在于阻止人们在未经许可的情况下使用他人的内容并使其看起来像自己的内容。)
Shameless Plug:请参阅我的书(Data Push Apps with HTML5 SSE,O'Reilly)中的第 9 章,以更好地控制 allow-origin,以及它如何与 cookie 和基本身份验证交互。
顺便说一句,我注意到我提到 Chrome 无法使用自签名 https 证书。老实说,我不确定情况是否仍然如此,但在使用 https 和 localhost 时也可能需要注意这一点。
关于google-chrome - 事件源修改协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46611145/