2009-05-15 2 views
14

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

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

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

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

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

+1

Вы можете предотвратить несколько нажатий кнопки отправки, используя некоторый javascript, но я также хотел бы получить ответ для части «анимация». –

+2

Решение, которое я использую сейчас, - это разделение генерации и загрузки на две части, поэтому при создании файла браузер получает еще одну HTML-страницу с ссылкой для загрузки. Однако это не создает файлы «на лету», и я бы очень хотел узнать, как это сделать. –

+1

Предложение отключить кнопку отправки кажется разумным, но есть ли способ включить его снова, когда создание файлов завершено? Если нет, то в основном такая же проблема. – audras

ответ

5

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

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

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

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

-1

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

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

1

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

+0

Это медленное поколение PDF-файла, вы должны сохранить его статус/прогресс где-нибудь для AJAX, чтобы получить его. Опрос AJAX не является окончательным решением. –

+0

Я знаю, что требуется для разработки этого решения. Вы можете опросить, например, через 5-10 секунд, это не обязательно должно быть в реальном времени. Все зависит от того, что вы хотите от пользователя. Но в этом случае трудно найти другое решение или вы убеждены в другом? – Kevin

+0

И действительно, AJAX/опрос не является окончательным решением. – Kevin

0

Я бы поместил это или что-то в этом случае в событие 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; } 
2

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

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

Я считаю, что this blog on asp.net обсуждает аналогичную установку.

0

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

В то же время, я попробовал еще один подход:

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

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

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

+0

Или второй загрузчик может просто отображать ссылку на файл, если браузер основан на IE; что нетрудно обнаружить. –

2

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

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

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

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

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

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

Смежные вопросы