跨浏览器服务器发送的事件,或替代方案,包括 Microsoft 浏览器

Cross browser Server-sent Events, or alternative, including Microsoft browsers

根据Can I use?, the MS IE & Edge browsers do not support Server-sent Events

有解决办法吗?

或者一个完全跨浏览器的替代方案,它非常简单(websockets 似乎不是这样(而且,无论如何,我更喜欢坚持使用 HTTP,而不是同时使用多个协议使事情复杂化)) ?

我希望 AngularJs 客户端能够订阅和取消订阅 PHP 服务器推送的 JSON 数据,多个客户端能够订阅相同的数据并且只能订阅一个服务器需要采取行动来推动它,最好是不知道要推动它给谁。

Microsoft 对 SSE 的固执令人难以置信,尤其是实现它实际上只是 XMLHttpRequest2 的一层,标准很短,3 年来已经有一本很棒的 O'Reilly 书出版了,并且至少有两个开源实现可以从中汲取灵感。

无论如何,要使兼容性恢复到 IE8,推荐的技术是创建一个隐藏的 iframe,然后继续轮询其内部源,并且 return 那里的任何新内容:

iframe = document.createElement("iframe");
iframe.setAttribute("style", "display: none;");
iframe.setAttribute("src", "abc_stream.php");
document.body.appendChild(iframe); 

如果只需要支持回IE10,可以使用XMLHttpRequest2对象,收听readyState==3消息:

xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    //Read this.responseText from the previous offset onwards
    };
var u = url;   
u += "xhr=1&t=" + (new Date().getTime());
xhr.open("GET", u);

这些技术在 back-end 上只需要非常轻微的支持:如果客户端使用真正的 SSE 连接,您必须将 MIME 类型设置为 text/event-stream,但是如果使用 xhr hack,您必须将其设置为 text/plain。我将它附加 xhr=1 到 URL,如上所示(以及停止缓存的时间戳)。

xhr 技术适用于支持 SSE 的所有浏览器,如果您确实想要单一解决方案的话。缺点之一是发送的完整数据会在内存中累积。 (我的建议是 auto-reconnect 只要 responseText 超过 64KB 或类似的东西。)

有几个用于 MSIE 的 EventSource polyfill:

https://github.com/remy/polyfills/blob/master/EventSource.js

https://github.com/amvtek/EventSource

其中一个(不记得是哪个)会定期显示烦人的警报消息,因此您可能需要编辑代码并将其删除。

您可以在这里找到一个用法示例:

https://github.com/mariomac/jeasse/blob/master/examples/chat-servlet3/src/main/resources/static/index.html