客戶端從服務器請求網頁。然後請求額外的計算完成;服務器執行一系列計算並在可用時立即發送部分結果(文本格式,每行包含單獨的完整項目)。客戶端使用服務器提供的信息更新網頁(使用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