一尘不染

处理连续的JSON流

json

(现已失效)页面http://stream.twitter.com/1/statuses/sample.json用于返回连续无休止的JSON数据流。

我想在自己的网页中使用jQuery(或JavaScript,但最好是jQuery)对其进行处理,以便能够基于实时推文显示视觉效果。

据我所知,jQuery
parseJSON函数仅在服务器发送完所有数据后才执行回调函数,但这实际上是连续的数据流。我如何“按需处理”数据,但仍保持连接运行?


阅读 303

收藏
2020-07-27

共1个答案

一尘不染

这种事情最好现在使用WebSockets完成,根据CanIUse.Com的说明,该协议
Opera
Mini以外的所有主要浏览器中都可用(请参阅该链接以获取有关旧版或所有浏览器的更多详细信息,然后单击“资源”选项卡以查看更多链接)
。作为概述,IE 10 +,Firefox 11+(如果在WebWorker上下文中为38 +),Chrome 16 +,Opera 12.1
+,Safari 7 +,Android 4.4 +,Opera Mobile 12.1+支持websocket。

注意:您可能还想了解 Service Worker和Web
Worker
,尽管它们具有不同的用例和不同的功能。

看起来像这样:

var connection = new WebSocket(
   'ws://html5rocks.websocket.org/echo',
   ['soap', 'xmpp']
);

立即将一些事件处理程序附加到连接上,可以让您知道何时打开连接,何时收到传入消息或是否发生错误。

发送消息变得像这样简单:

connection.send('your message');
connection.send(binaryData);

有关如何执行此操作的完整说明,请参见WebSockets:将套接字引入Web

ASP.Net开发人员:如果由于某种原因您需要支持较旧的浏览器,并且不想自己弄清楚如何处理不支持WebSocket的浏览器,请考虑使用SignalR之类的库。

适用于旧浏览器的旧EventSource API答案

现在,大多数浏览器都实现了EventSource API,只要可以使用content-type传递流,就可以使长时间轮询真正容易text/event- stream。较旧的浏览器或由于任何原因而无法设计流以使其具有该内容类型的那些开发人员,可以使用一些帮助程序脚本来执行相同的操作。

这是一个例子:

var jsonStream = new EventSource('https://example.com/yourstreamingservice')
jsonStream.onmessage = function (e) {
   var message = JSON.parse(e.data);
   // handle message
};

这基本上是我在下面概述的确切内容的完整版本。

真正古老的浏览器的更老的服务流式答案

您想要的就是长轮询。您将需要一个自定义的AJAX
onreadystatechange处理功能。您不必等到整个流完成(因为它永远不会完成),而是需要定期检查内容。请注意,您需要使用进行一些繁重的工作,以使其在IE
9及更低版本中工作iframe

大致:

  • 响应每个onreadystatechange事件并检查已被赋予当前角色的流,以查看是否有足够的数据消耗一个或多个离散事件。您需要使用javascript字符串处理函数自己解析流。split,indexOf,正则表达式,循环等的组合可用于完成此任务。
  • 如果内容还不够,请退出并等待下一个事件。
  • 我很确定,每次onreadystatechange处理程序触发时,responseText将是到目前为止已接收的所有数据。定义一个持久变量,该变量将保存尚未正确处理的第一个字符的位置。
  • 一旦有足够的内容使一个或多个离散事件出现在流中,则一次将它们取出,然后将它们传递给JSON解析器,以将文本实际呈现为对象。正常使用它们。

请查看此HTTP
Streaming要点
中的一种资源,或查看Streaming作为在SoftwareAs
上轮询服务器的替代方法。如果必须支持IE 9或更早版本,则需要使用该iframe方法。

这是《Ajax设计模式:使用编程和可用性模式创建Web
2.0站点
》一书的引文

总之,由于您可以流传输任意内容而不是Javascript命令,并且可以控制连接的生命周期,因此服务流使HTTP流方法更加灵活。但是,它结合了两种在浏览器之间不一致的技术,以及可预测的可移植性问题。实验表明,Page
Streaming技术在IE [9及更早版本]和Firefox上均适用,但是Service
Streaming仅在Firefox上有效,无论使用XMLHTTPRequest还是IFrame。在第一种情况下,IE
[9和更早版本]抑制响应直到完成为止,如果使用了解决方法,则使用IFrame,它可以工作:IE
[9和更旧版本]在前256个字节之后接受来自服务器的消息,因此在发送消息之前,先发送256个虚拟字节。此后,所有消息将按预期到达。

请注意,这是从2006年开始的,因此绝对过时了,但是如果您必须支持较旧的浏览器,那么它仍然很重要。

安全问题

普通的AJAX不能跨域使用,这意味着(现在我要注意您要从Twitter流式传输的事实),您将无法执行您所要求的操作。可以使用JSONP解决此问题,但是JSONP本质上无法进行服务流传输,而且Twitter也不会提供。还有跨域资源共享(CORS),但twitter不会为您设置它-
那是他们只对与它们关联的域进行的操作。而且,CORS需要现代的浏览器。

因此,唯一的选择是在Web服务器上创建代理服务,该代理服务为您执行对twitter的请求,然后分发数据。这只能在与提供主页相同的域中进行。这样做还可以让您使用iframe技术创建适用于IE的版本。如果您不关心旧的IE版本,则可以通过自己实现CORS来克服域限制(如果您知道将发出请求的域)。

如果您完全控制客户端软件(例如,这是用于公司Intranet),则还有另一种选择:将Web浏览器托管在已编译的本地执行的应用程序的用户表单中。我只使用C#完成了此操作,但我想其他语言也可能做到这一点。当您使用正确的浏览器对象时,由于该对象托管在C#应用程序中,因此C#应用程序可以克服跨域安全性限制,无论其来自哪个域,都可以读取和写入所有页面内容。我怀疑您的情况就是这种情况,但我想在这里为其他可能会喜欢它的人提供选择。

2020-07-27