Веб-страница запроса клиента с сервера. Затем Клент требует дополнительных вычислений; сервер выполняет серию вычислений и отправляет частичные результаты, как только они доступны (текстовый формат, каждая строка содержит отдельный полный элемент). Клиент обновляет веб-страницу (с помощью JavaScript и DOM), используя информацию, предоставленную сервером.Кросс-браузерная реализация «HTTP Streaming» (push) AJAX pattern
Это похоже на HTTP Streaming (current) шаблон с сайта Ajaxpatterns.
Вопрос в том, как это сделать в кросс-браузерном (обозревателе агностическом) способом, желательно без использования фреймворков JavaScript или с использованием некоторой облегченной структуры, такой как jQuery.
Проблема начинается с генерации XMLHttpRequest в кросс-браузере, но я считаю, что основным элементом является то, что не все браузеры правильно реализуют onreadystatechange
от XMLHttpRequest; не все браузеры вызывают onreadystatechange
событие на каждом сервере flush (BTW. как заставить сервер закрашиваться из CGI-скрипта (в Perl)?). Пример кода на Ajaxpatterns касается этого, используя таймер; следует ли отказаться от решения таймера, если я обнаруживаю частичный ответ от onreadystatechange
?
Добавлено 11-08-2009
Текущее решение:
Я использую следующую функцию для создания объекта 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»? – Basic
Привет, только что наткнулся на ваше решение, но я боюсь, что он по-прежнему не будет работать с IE, поскольку, когда вы попытаетесь получить ответText, пока запросы еще не закончились, вы получите следующее message: «Данные, необходимые для завершения этой операции, пока недоступны». –