(现已失效)页面http://stream.twitter.com/1/statuses/sample.json用于返回源源不断的JSON数据。
我想在我自己的网页中使用jQuery(或JavaScript,但最好是jQuery)来处理它,以便能够显示基于实时推文的视觉效果。
据我所知,jQueryparseJSON
函数只会在服务器发送完所有数据后执行回调函数,但这实际上是一个连续的数据流。如何在"发生时"处理数据的同时保持连接运行?
这类事情现在最好使用WebSockets来完成,根据CanIUse.Com的说法,WebSockets在除Opera Mini之外的所有主要浏览器中都可用(有关旧浏览器或所有浏览器的更多详细信息,请参阅该链接,并单击"资源"选项卡查看更多链接)。总之,IE 10+、Edge 12+、Firefox 11+(如果在WebWorker上下文中,则为38+)、Chrome 16+、Opera 12.1+、Safari 7+、Android 4.4+、OperaMobile 12.1+都支持websocket。
注意:您可能也想了解Service Workers和Web Workers,尽管它们有不同的用例和不同的能力
它看起来像这样:
var connection = new WebSocket(
'ws://html5rocks.websocket.org/echo',
['soap', 'xmpp']
);
将一些事件处理程序立即附加到连接可以让您知道连接何时打开、何时收到传入消息或是否发生错误。
发送消息变得如此简单:
connection.send('your message');
connection.send(binaryData);
有关如何做到这一点的完整解释,请参阅介绍WebSockets:Bring Sockets to the Web。
ASP.Net开发人员:如果出于某种原因,您需要支持较旧的浏览器,并且不想自己解决如何处理那些不支持WebSocket的浏览器,请考虑使用SignalR等库。
旧版浏览器的旧EventSource API答案
现在大多数浏览器都实现了EventSource API,这使得长时间轮询非常容易,只要流可以使用内容类型text/event-stream
来传递。较旧的浏览器或那些由于任何原因无法设计流以具有该内容类型的开发人员可以使用一些辅助脚本来做同样的事情。
这里有一个例子:
var jsonStream = new EventSource('https://example.com/yourstreamingservice')
jsonStream.onmessage = function (e) {
var message = JSON.parse(e.data);
// handle message
};
这基本上是我在下面概述的事情的一个完整版本。
适用于真正旧浏览器的更旧的服务流式传输答案
你想要的是所谓的长轮询。您需要一个自定义的AJAXonreadystatechange
处理函数。您需要定期检查内容,而不是等到整个流完成(因为它永远不会完成)。请注意,为了在IE 9及更低版本中使用iframe
,您需要进行一些繁重的工作。
大致:
- 响应每个
onreadystatechange
事件,并检查当前角色的流,以查看是否有足够的数据来使用一个或多个离散事件。您需要使用javascript字符串处理函数自己解析流。split、indexOf、正则表达式、循环等的组合可用于完成此任务 - 如果内容还不够,请退出并等待下一个事件
- 我非常确信,每次
onreadystatechange
处理程序触发时,responseText
都将是迄今为止接收到的所有数据。定义一个持久变量,该变量将保存尚未正确处理的第一个字符的位置 - 一旦有足够的内容让一个或多个离散事件出现在流中,就一次取出一个,并将它们传递给JSON解析器,以便将文本实际呈现为对象。正常使用
查看一个资源的HTTP流式处理要点,或者流式处理作为在SoftwareAs轮询服务器的替代方案。如果必须支持IE 9或更旧版本,则需要使用iframe
方法。
这里引用了《Ajax设计模式:用编程和可用性模式创建Web2.0网站:》一书
总之,服务流式传输使HTTP流式传输方法更加灵活,因为您可以流式传输任意内容,而不是Javascript命令,而且您可以控制连接的生命周期。然而,它结合了两种在浏览器之间不一致的技术,存在可预测的可移植性问题。实验表明,页面流技术确实适用于IE[9及更早版本]和Firefox,但无论使用XMLHTTPRequest还是IFrame,服务流仅适用于Firefox。在第一种情况下,IE[9及更早版本]会抑制响应直到其完成,如果使用了变通方法,则IFrame会起作用:IE[9或更早版本]在前256个字节之后接受来自服务器的消息,因此唯一要做的就是在发送消息之前发送256个伪字节。在此之后,所有消息都将按预期到达。因此,在IE[9及更早版本]中也可以实现全服务流媒体!
请注意,它是2006年的,所以它肯定已经过时了,但如果你必须支持旧的浏览器,它仍然是相关的。
安全问题
普通的AJAX不能跨域,这意味着(现在我注意到你想从twitter流式传输)你将无法执行你的要求。这可以通过JSONP解决,但JSONP本质上不能进行流式服务,而且twitter也不提供。还有跨来源资源共享(CORS),但推特不会为你设置这一点——这是他们只会为与他们有关联的域名做的事情。CORS需要一个现代化的浏览器。
因此,你唯一的选择是在你的网络服务器上创建一个代理服务,为你执行对twitter的请求,然后分发数据。这只能在提供主页的同一域中完成。这样做还可以使用iframe技术创建一个适用于IE的版本。如果你不关心旧的IE版本,如果你知道将发出请求的域,你可以自己实现CORS来克服域限制。
如果你可以完全控制客户端软件(比如这是针对企业内部网的),还有另一种选择:在编译的本地执行应用程序的用户表单中托管web浏览器。我只使用C#实现了这一点,但我认为其他语言也可以实现。当您使用正确的浏览器对象时,因为它托管在C#应用程序中,所以C#应用程序可以克服跨域安全限制,读取和写入所有页面内容,无论它来自哪个域。我怀疑你的情况是这样的,但我想把这个选项放在这里给其他可能会欣赏它的人
我有一个开源项目,它在现代浏览器上允许这样做(在旧浏览器上又回到了jQuery风格)。调用语法类似于jQuery.ajax:
http://oboejs.com
您在问题中指定的url发送JSON响应流。由于浏览器中的跨域安全限制,您无法使用javascript访问它。您需要在服务器上实现一个桥接服务器端脚本,您可以使用AJAX请求定期轮询,或者在twitter.com
上托管您的网站。第一种似乎更可行。
一个非常基础的网页无法保持与服务器的实时/运行连接。Web浏览器向服务器发送请求。服务器将响应(HTML等)发送回客户端(web浏览器)。将其视为一个无状态模型——在请求和响应完成后,任何连接都不会保持活动状态。
因此,你必须自己做。您必须从客户端调用额外的定期请求。
一种方法是通过setInterval()函数定期调用AJAX/GET功能。例如:
setInterval(function() {
$.ajax({
url: "mydata/get",
success: function(){
// update content.
}
});
}, 5000);
这将每隔5秒向mydata/get(或您想要使用的任何URL)发出一个AJAX请求。