【发布时间】:2010-11-09 21:21:54
【问题描述】:
客户端从服务器请求网页。然后 Clent 要求进行额外的计算;服务器执行一系列计算并在部分结果可用时立即发送(文本格式,每行包含单独的完整项目)。客户端使用服务器提供的信息更新网页(使用 JavaScript 和 DOM)。
这似乎符合 Ajaxpatterns 网站的 HTTP Streaming(current 版本)模式。
问题是如何以跨浏览器(与浏览器无关)的方式进行操作,最好不使用 JavaScript 框架,或者使用一些轻量级框架,如 jQuery。
问题始于以跨浏览器方式生成 XMLHttpRequest,但我认为主要是并非所有浏览器都正确实现 onreadystatechangefrom XMLHttpRequest;并非所有浏览器都会在每个服务器刷新时调用 onreadystatechange 事件(顺便说一句。如何从 CGI 脚本(在 Perl 中)强制服务器刷新?)。 Ajaxpatterns 上的示例代码通过使用计时器来处理这个问题;如果我检测到来自onreadystatechange 的部分响应,我应该放弃计时器解决方案吗?
添加于 2009 年 8 月 11 日
当前解决方案:
我使用以下函数创建 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;
}
如果我要使用一些(最好是轻量级的)JavaScript 框架,比如 jQuery,如果用户选择不安装 jQuery,我希望有备用。
我使用下面的代码来启动 AJAX;使用setInterval 是因为某些浏览器仅在服务器关闭连接后(可能需要长达数十秒)才调用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;
}
【问题讨论】:
-
您绝对应该将该代码示例添加为回复并将其标记为正确的!
-
"如果用户选择不安装 jQuery" ?
-
嗨,刚刚遇到了您的解决方案,但恐怕它仍然无法与 IE 一起使用,因为当您尝试在请求仍未结束时获取 responseText 时,那么您将收到以下消息:“完成此操作所需的数据尚不可用”。
标签: javascript ajax streaming xmlhttprequest comet