Есть ли события обновления прогресса в jQuery ajax?

У меня есть давно запущенная задача, которая вызывается с помощью jquery ajax. Я использую плагин пользовательского блока, чтобы показать "загрузка". есть ли в любом случае, я могу отправлять сообщения о прогрессе обратно клиенту, чтобы показать прогресс и обновить его в сообщении плагина block ui.

Так что это покажет (как сервер выполняет свою работу) .,

"Загрузка первого источника..."
"Загрузка второго источника..."
"Загрузка третьего источника..."
"Анализ результатов..."

6 ответов

Решение

Из того, что я видел в случае загрузки материала - люди создают отдельный шлюз и запрашивают информацию о прогрессе, так как он доступен только на стороне сервера. Но я думаю, что это не самое лучшее в вашем случае.

Если вы хотите загружать данные с информацией о прогрессе или разрешать серверу получать информацию о прогрессе во время генерации вывода, тогда вам нужна потоковая передача http. Здесь красиво покрыто. По сути, это один http-запрос, на который сервер отвечает частями в течение минуты или около того (следовательно, отправляет данные, когда хочет), а затем открывается новое соединение.

Это было настоящим открытием для меня;)

[редактировать]

В настоящее время существует множество доступных более совершенных методов, и все они заключены в Socket.IO - веб-сокеты с отступлением от других методов, включая потоковую передачу по протоколу http.

Socket.IO - это модуль для nodeJS, но есть и другие похожие реализации. Я уже обменялся некоторыми пакетами с реализацией JAVA Socket.IO с https://github.com/Atmosphere/atmosphere

Один из способов - использовать HTTP-обработчики и AJAX с jQuery.

1. Инициируйте запрос на стороне сервера

$("#btnCreateInvoice").click(function() {             
       $.ajax({ type: "POST",  url: "YourHttpHandler.ashx",
       contentType: "text/html; charset=utf-8",
       dataType: "html",  
       success: function(data) { start the block UI }
       });
    });

2. Опрос

Далее вам нужно опросить сервер с интервалом "t" и получить статус. Для этого нам нужно вызывать функцию с интервалом 't', которая инициировала бы вызов AJAX HTTP Handler для получения статуса.

$(function() {
  setInterval(updateStatus, 't');
});

function updateStatus() {
  $.ajax({ type: "POST",  url: "GetStatusHandler.ashx",
       contentType: "text/html; charset=utf-8",
       dataType: "html",  
       success: function(data) { process 'data' here and update the block UI message box }
       });
}

В вашем случае, GetStatusHandler.ashx может вернуть полный innerHtml для статуса. Например, при первом вызове он вернет "Загрузка первого источника...", а затем может вернуть:
Loding Первый источник...
Загрузка Второй источник...
и так далее.

Я хотел бы, чтобы каждый запрос AJAX возвращал ответ JSON, содержащий сообщение, данные и следующий URL-адрес для запроса: {message: "Loading second resource...", data: ..., next_url: "/next_part"}

Перед вашим первым AJAX-запросом установите для сообщения BlockUI значение "Загрузка...". Получив ответ, установите в сообщении BlockUI сообщение, полученное вами после вызова AJAX. Затем выполните следующий вызов AJAX со значением "next_url" и т. Д., Зацикливаясь до тех пор, пока вы не выполните все задачи.

Если вы загружаете один большой набор данных, но по частям, вы можете захотеть сделать что-то вроде шаблона проектирования с прогрессивной загрузкой, но также установить сообщение о ходе выполнения при получении каждого ответа.

Я только недавно узнал о проекте, который делает ajax "push". Вы можете проверить это:

http://www.ape-project.org/

Насколько я знаю, есть несколько других проектов, которые делают подобные вещи, это самый правильный способ: "отправлять сообщения о прогрессе обратно клиенту", когда другое решение требует запрос на опрос о прогрессе (все еще очень законный и хороший решение).

То, что вы пытаетесь сделать, это нечто похожее на комету. Традиционные ("некометные") веб-серверы не предназначены для такой модели транзакций и поэтому не являются желаемым решением.

Я предлагаю разбить обработку по одному клиентскому запросу на источник данных:

function loadData() {
   // Each call passes callback(id) as a success handler
   fireAsynchronousRequest("source1");
   fireAsynchronousRequest("source2");
   fireAsynchronousRequest("source3");
}

function callback(var source) {
   if (source == "source1") {
       updateStatus("Source 1 loaded");
   }
   else if (source == "source2") {
       updateStatus("Source 2 loaded");
   }
}

Это пример асинхронного решения. Вы можете реализовать обработку состояний в callback() если вам нужно, чтобы это было синхронно.

Ну, у меня была похожая ситуация, и я решаю ее другим подходом. Это ОЧЕНЬ уродливое решение, я знаю это, поэтому, пожалуйста, не начинайте указывать, насколько это плохо, потому что я знаю это, но это было нормально для того, что мне нужно.

Я помещаю прогресс в файл на стороне сервера. Например, у меня есть файл process.php, который должен выполнить большую работу, и до его завершения требуется некоторое время, поэтому пользователь нервничает и закрывает браузер (не слишком хорошо). Таким образом, process.php сохраняет некоторые выходные данные в файл на сервере. На странице, которая называется process.php, у меня есть небольшой div, span или что-то еще, где я хочу отобразить прогресс, но я предлагаю div. Каждую X миллисекунду или секунду я загружаю другой сценарий с сервера в div, скажем, display_info.php. Теперь display_info.php читает файл, который был обработан process.php, а содержимое отображается в div.

Вы должны быть осторожны, чтобы выходные данные из process.php были уникальными для каждого случая, в противном случае вы запутаете вывод информации в браузерах.

Эмиль

Другие вопросы по тегам