客户端从服务器请求网页。然后请求额外的计算完成;服务器执行一系列计算并在可用时立即发送部分结果(文本格式,每行包含单独的完整项目)。客户端使用服务器提供的信息更新网页(使用JavaScript和DOM)。“HTTP流式传输”(推送)AJAX模式的跨浏览器实现
这似乎适合来自Ajaxpatterns网站的HTTP Streaming(current版本)模式。
问题是如何以跨浏览器(浏览器不可知)的方式做到这一点,最好不使用JavaScript框架,或使用像jQuery这样的轻量级框架。
问题始于跨浏览器方式生成XMLHttpRequest,但我认为主要内容是并非所有浏览器都能正确实现onreadystatechange
XMLHttpRequest;并非所有浏览器都在每个服务器上调用onreadystatechange
事件flush(顺便说一下,如何强制从CGI脚本(Perl中)刷新服务器?)。 Ajax模式上的示例代码通过使用定时器来处理此问题;如果我检测到来自onreadystatechange
的部分响应,我应该放弃定时器解决方案吗?
新增2009年11月8日
目前的解决方案:
我用下面的函数来创建XMLHttpRequest对象:
function createRequestObject() {
var ro;
if (window.XMLHttpRequest) {
ro = new XMLHttpRequest();
} else {
ro = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!ro)
debug("Couldn't start XMLHttpRequest object");
return ro;
}
如果我使用一些(最好是轻量级的)像jQuery这样的JavaScript框架,如果用户愿意的话可以使用fallback选择不安装jQuery。
我使用下面的代码启动AJAX;使用setInterval
是因为某些浏览器只有在服务器关闭连接(可能需要几十秒)后才会调用onreadystatechange
,而不是在服务器刷新数据(每秒钟或更频繁)后才立即调用onreadystatechange
。
function startProcess(dataUrl) {
http = createRequestObject();
http.open('get', dataUrl);
http.onreadystatechange = handleResponse;
http.send(null);
pollTimer = setInterval(handleResponse, 1000);
}
的handleResponse
功能是最复杂的一个,但它的草图如下所示。它可以做得更好吗?如何使用一些轻量级的JavaScript框架(如jQuery)来完成?
function handleResponse() {
if (http.readyState != 4 && http.readyState != 3)
return;
if (http.readyState == 3 && http.status != 200)
return;
if (http.readyState == 4 && http.status != 200) {
clearInterval(pollTimer);
inProgress = false;
}
// In konqueror http.responseText is sometimes null here...
if (http.responseText === null)
return;
while (prevDataLength != http.responseText.length) {
if (http.readyState == 4 && prevDataLength == http.responseText.length)
break;
prevDataLength = http.responseText.length;
var response = http.responseText.substring(nextLine);
var lines = response.split('\n');
nextLine = nextLine + response.lastIndexOf('\n') + 1;
if (response[response.length-1] != '\n')
lines.pop();
for (var i = 0; i < lines.length; i++) {
// ...
}
}
if (http.readyState == 4 && prevDataLength == http.responseText.length)
clearInterval(pollTimer);
inProgress = false;
}
您应该将该代码示例添加为回复并将其标记为正确的! – 2012-01-04 14:18:31
“如果用户选择不安装jQuery”? – Basic 2012-07-17 16:56:04