Индикатор прогресса / занятости во время ожидания загрузки файла в javascript? - PullRequest
14 голосов
/ 15 мая 2009

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

Проблема: Генерация PDF файла занимает довольно много времени (до 1 минуты). Некоторые пользователи думают, что ничего не происходит, и продолжают нажимать кнопку отправки снова и снова, увеличивая нагрузку на сервер и еще больше замедляя ее.

Я хотел бы добавить индикатор занятости, который бы отображал анимированную картинку и сообщение типа «Пожалуйста, подождите, ваш файл генерируется», что кажется очень простым делом.

Но: как скрыть этот индикатор, когда файл готов и появляется диалоговое окно «Загрузка файла»? В противном случае сообщение остается на экране даже после того, как пользователь скачал файл!

Кажется очень основным требованием, но я полностью застрял. Спасибо за любые предложения!

Ответы [ 7 ]

5 голосов
/ 15 мая 2009

Я должен был сделать это для чего-то, что заняло намного больше времени (преобразование формата видео). Это может показаться вам излишним, но это сработало.

  1. Переместите ваш PDF-код из процесса.
  2. Когда задание запущено, создайте уникальный идентификатор задания и сохраните его в сеансе. Сообщите создателю PDF-документа этот идентификатор.
  3. Заставьте его записать файл состояния (называемый идентификатором задания) на сервер, чтобы он записывал «0% завершено» и обновлял его каждые несколько секунд (эта часть зависит от того, можете ли вы иметь показатель прогресса в своем процессе ... если этого не произойдет, то это не сработает)
  4. Используйте JS, чтобы вытащить этот файл вниз. Вы можете отобразить прогресс для пользователя.
  5. Когда ход выполнения будет равен «100% завершен», отправьте их в папку PDF. Это может помочь, если вы также укажете это как идентификатор работы. *

* У нас был еще один сценарий загрузки, который переименовал его в красивое имя (на основе исходного имени файла видео) с использованием заголовка расположения контента, но это действительно ваше дело!

Редактировать: я должен добавить, что страница ожидания была результатом нажатия кнопки Отправить. Это была новая загрузка страниц, но нет никаких причин, по которым вы не могли AJAX весь процесс, просто убедитесь, что, как уже говорили другие, отключите кнопку отправки по первому щелчку, чтобы пользователь не обращал на нее внимания.

2 голосов
/ 04 января 2011

У меня есть запись в блоге с потенциальным решением этой проблемы:

http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx

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

  • Пользователь нажимает кнопку «Отправить» для создания файла. До данные отправляются на сервер для обработки, JavaScript на стороне клиента делает три вещи:
    1. Создает значение "токен" и устанавливает скрытое поле в HTML-форме, которая должна быть отправлена. Значение токена не очень важно; достаточно просто использовать текущую отметку даты и времени, и второй секунды будет достаточно.
    2. Сразу после установки токена, но еще до того, как разрешить отправку формы, код на стороне клиента выдает сообщение «system busy», чтобы оба пользователя знали, что что-то произошло, и не позволяли им отправлять форму дважды. Плагин jQuery BlockUI отлично подходит для этой цели.
    3. Наконец, время настроено на периодический опрос на наличие куки с заранее заданным именем, содержащим значение токена, созданное на шаге 1.
  • Теперь у вас есть приятная «обложка» на стороне клиента, которая позволяет пользователю узнать, что что-то происходит, и не позволяет ему дважды нажать кнопку, пока запрос может быть обработан на стороне сервера. Непосредственно перед отправкой заполненного файла обратно клиенту для загрузки установите cookie-файл с предварительно определенным именем в HTTP-ответе, который содержит значение токена, которое было отправлено клиентом.
  • Когда клиент получает ответ HTTP, код таймера, который опрашивает предварительно определенное имя файла cookie, содержащее значение токена, найдет его и может затем сделать следующее:
    1. Разблокировать пользовательский интерфейс
    2. Остановите таймер / код опроса.

Обычно я делаю это с интервалом опроса в 1 секунду, поэтому большинству пользователей приходится ждать 1 секунду между временем, когда диалоговое окно загрузки файла отображается в их браузере, и временем, когда сообщение "system busy" исчезает.

Этот подход, на мой взгляд, очень быстрый и простой в реализации. Тем не менее, учитывая, что создание вашего PDF занимает около 1 минуты, я думаю, вы приближаетесь к тому моменту, когда предпочтительнее взять обработку «вне диапазона» и реализовать нечто подобное тому, что было объяснено в принятом ответе.

2 голосов
/ 15 мая 2009

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

Один из способов реализации строки состояния или обновления сообщения об ожидании состоит в том, чтобы клиентский JavaScript выполнял первоначальный вызов серверу и сразу же отвечал серверу, как только он начнет генерировать. Затем вы можете заставить клиентский JavaScript опрашивать сервер каждые n секунд, чтобы увидеть, завершен ли файл. Если у вас есть способ определения состояния генерации файла, вы можете вернуть числовой ответ в процентах от индикатора выполнения или просто ответить сообщением с «все еще работающим» типом.

Я считаю, что в этом блоге на asp.net обсуждается аналогичная настройка.

1 голос
/ 15 мая 2009

Вы можете асинхронно опрашивать сервер (например, с помощью AJAX), чтобы проверить, завершено ли создание этого конкретного PDF-файла. В зависимости от этого результата или тайм-аута снова включите эту кнопку и / или остановите анимацию.

0 голосов
/ 15 мая 2009

Спасибо всем за предложения.

Тем временем я попробовал еще один подход:

a) В «onclick» отключите кнопку отправки и покажите индикатор занятости. б) На стороне сервера, когда файл генерируется, не выводите его пользователю, а сохраняйте в файловую систему. Затем отправьте перенаправление на ту же страницу, но с атрибутом "& downloadready = true" c) При загрузке страницы, если атрибут «downloadready» имеет значение true, начать загрузку файла.

Это работает, но имеет один недостаток: в IE было показано предупреждение "Чтобы защитить вашу безопасность, IE заблокировал загрузку файлов, что бла-бла-бла", что, я полагаю, было бы довольно раздражающим для пользователей.

Итак, давайте попробуем подход опроса AJAX.

0 голосов
/ 15 мая 2009

Я бы поместил это или что-то подобное в событие onSubmit. Блок Busy может быть просто div с анимацией ajax load ing в фоновом режиме. (Я предлагаю анимированный GIF вместо анимации Javascript.) Как только выходные данные возвращаются, пользователь увидит PDF после своего минутного ожидания. Вы можете даже использовать таймер, чтобы уменьшить оценку (скажем, 60 секунд) и дать пользователю представление о том, сколько времени это может занять.

document.getElementById('busy').style.display = 'block';
document.getElementById('submit').disabled = 'disabled';

Занятый блок:

<div id="busy">
  <p>Your PDF is being generated, please wait.</p>
</div>

И общий CSS ...

#busy { display: none; background: url(/images/spinner.gif) no-repeat top left; padding-left: 24px; }
0 голосов
/ 15 мая 2009

Не полный ответ на ваш вопрос, но вы можете отключить кнопку отправки, когда пользователь сделал первый щелчок.

Это решит проблему «пользователь продолжает щелкать, тем самым замедляя работу сервера».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...