Strona internetowa żądania klienta z serwera. Clent prosi o dodatkowe obliczenia; serwer wykonuje serię obliczeń i wysyła wyniki cząstkowe, gdy tylko są dostępne (format tekstowy, każda linia zawiera oddzielny pełny element). Strona internetowa aktualizacji klienta (z JavaScript i DOM) przy użyciu informacji dostarczonych przez serwer.Wbudowana w przeglądarki wersja "HTTP Streaming" (push) AJAX pattern
Wydaje się to pasować do wersji HTTP Streaming (current) z witryny Ajaxpatterns.
Pytanie brzmi: jak to zrobić w sposób umożliwiający przeglądanie w różnych przeglądarkach (z pominięciem przeglądarki), najlepiej bez korzystania z frameworków JavaScript lub przy użyciu jakiegoś lekkiego frameworka, takiego jak jQuery.
Problem zaczyna się od wygenerowania XMLHttpRequest w modzie w różnych przeglądarkach, ale myślę, że głównym elementem jest to, że nie wszystkie przeglądarki implementują poprawnie onreadystatechange
z XMLHttpRequest; nie wszystkie przeglądarki wywołują zdarzenie onreadystatechange
na każdym spłukiwaniu serwera (BTW, jak wymusić spłukanie serwera z poziomu skryptu CGI (w Perlu)?). Przykładowy kod na Ajaxpatterns radzi sobie z tym za pomocą timera; czy powinienem zrezygnować z rozwiązania czasomierza, jeśli wykryję częściową odpowiedź z onreadystatechange
?
Dodany 11-08-2009
Aktualny rozwiązanie:
używam następującą funkcję do stworzenia obiektu 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;
}
Gdybym miał użyć niektóre (najlepiej lekki) framework JavaScript jak jQuery, chciałbym mieć awarię, jeśli użytkownik nie instaluje jQuery.
Używam następującego kodu, aby uruchomić AJAX; setInterval
jest używany, ponieważ niektóre przeglądarki wywołują onreadystatechange
tylko po zamknięciu połączenia przez serwer (co może potrwać nawet kilkadziesiąt sekund), a nie tak szybko, jak serwer opróżnia dane (co sekundę lub częściej).
function startProcess(dataUrl) {
http = createRequestObject();
http.open('get', dataUrl);
http.onreadystatechange = handleResponse;
http.send(null);
pollTimer = setInterval(handleResponse, 1000);
}
Funkcja handleResponse
jest najbardziej skomplikowany, ale szkic wygląda na to poniżej. Czy można to zrobić lepiej? Jak to zrobić przy użyciu niewielkiego szkieletu JavaScript (np. 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;
}
Powinieneś zdecydowanie dodać ten przykład kodu jako odpowiedź i oznaczyć go jako poprawny! –
"jeśli użytkownik nie instaluje jQuery"? – Basic
Cześć, właśnie natknąłem się na twoje rozwiązanie, ale obawiam się, że nadal nie będzie działać z IE, ponieważ kiedy spróbujesz uzyskać responseText, gdy żądania wciąż się nie kończą, otrzymasz następujące komunikat: "Dane niezbędne do ukończenia tej operacji nie są jeszcze dostępne". –