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

Posted

技术标签:

【中文标题】跨浏览器服务器发送事件,或替代方案,包括 Microsoft 浏览器【英文标题】:Cross browser Server-sent Events, or alternative, including Microsoft browsers 【发布时间】:2017-02-16 10:36:38 【问题描述】:

根据Can I use?,MS IE & Edge 浏览器不支持Server-sent Events。

有解决办法吗?

或者是一个完全跨浏览器的替代方案,它很简单(websockets 似乎不是(而且,在任何情况下,我更喜欢坚持使用 HTTP 并且没有多个同时协议使事情复杂化))?

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

【问题讨论】:

【参考方案1】:

微软对 SSE 的固执令人难以置信,尤其是实现它实际上只是在 XMLHttpRequest2 之上的一层,标准很短,3 年来一直有一本 O'Reilly 的精彩书籍,并且有至少有两个开源实现可以从中汲取灵感。

无论如何,让 IE8 兼容的推荐技术是创建一个隐藏的 iframe,然后继续轮询其内部源,并返回任何新的内容:

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);

这些技术只需要非常小的后端支持:如果客户端连接真正的 SSE,则必须将 MIME 类型设置为 text/event-stream,但如果使用 xhr hack,则必须将其设置为 @ 987654327@。我让它将xhr=1 附加到 URL,如上所示(以及阻止它被缓存的时间戳)。

xhr 技术将适用于 SSE 工作的所有浏览器,如果您确实想采用单一解决方案。它的一个缺点是正在发送的完整数据是在内存中建立的。 (我的建议是在 responseText 超过 64KB 或类似的大小时自动重新连接。)

【讨论】:

【参考方案2】:

有几个用于 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

【讨论】:

以上是关于跨浏览器服务器发送事件,或替代方案,包括 Microsoft 浏览器的主要内容,如果未能解决你的问题,请参考以下文章

Javascript Ajax总结——其他跨域技术之服务器发送事件SSE

Cordova/Phonegap - beforeunload 工作或任何替代方案?

CSS3旋转替代?

ajax请求请求数据缓存问题分析以及解决方案

WebSockets 还是 phonegap 的替代品?

Event Handler 事件处理程序 2 ---跨浏览器事件对象《高程3》