У меня есть страница, которая позволяет пользователю загружать динамически генерируемый файл. Генерирование занимает много времени, поэтому я хотел бы показать индикатор «ожидания». Проблема в том, что я не могу понять, как определить, когда браузер получил файл, поэтому я могу скрыть индикатор.
Я делаю запрос в скрытой форме, которая отправляет на сервер и нацеливает скрытый iframe для его результатов. Поэтому я не заменяю все окно браузера результатом. Я слушаю событие загрузки в iframe, в надежде, что оно сработает после завершения загрузки.
Я возвращаю заголовок «Content-Disposition: attachment» вместе с файлом, в результате чего браузер отображает диалоговое окно «Save». Но браузер не запускает событие загрузки в iframe.
Один из подходов, которые я попробовал, - это использование ответа из нескольких частей. Таким образом, он отправит пустой HTML-файл, а также прикрепленный загружаемый файл. Например:
Content-type: multipart/x-mixed-replace;boundary="abcde"
--abcde
Content-type: text/html
--abcde
Content-type: application/vnd.fdf
Content-Disposition: attachment; filename=foo.fdf
file-content
--abcde
Это работает в Firefox; он получает пустой HTML-файл, запускает событие «load», а затем показывает диалоговое окно «Save» для загружаемого файла. Но это не работает в IE и Safari; IE запускает событие «load», но не загружает файл, а Safari загружает файл (с неправильным именем и типом содержимого) и не запускает событие «load».
Другой подход может заключаться в том, чтобы позвонить, чтобы начать создание файла, затем опросить сервер, пока он не будет готов, а затем загрузить уже созданный файл. Но я бы предпочел не создавать временные файлы на сервере.
У кого-нибудь есть идея получше?
источник
Ответы:
Одно из возможных решений использует JavaScript на клиенте.
Клиентский алгоритм:
Алгоритм сервера:
Исходный код клиента (JavaScript):
Пример кода сервера (PHP):
Куда:
источник
Очень простое (и неудачное) однострочное решение - использовать
window.onblur()
событие, чтобы закрыть диалог загрузки. Конечно, если это займет слишком много времени и пользователь решит заняться чем-то другим (например, чтением писем), диалог загрузки закроется.источник
onbeforeunload
Спасибо.старая нить, я знаю ...
но те, которые приводятся здесь Google, могут быть заинтересованы в моем решении. это очень просто, но надежно. и это позволяет отображать сообщения о реальном прогрессе (и может быть легко подключен к существующим процессам):
сценарий, который обрабатывает (моя проблема заключалась в том, чтобы: извлекать файлы через http и доставлять их в формате zip) записывает состояние в сеанс.
статус опрашивается и отображается каждую секунду. вот и все (хорошо, это не так. вам нужно позаботиться о многих деталях [например, одновременных загрузках], но это хорошее место для начала ;-)).
страница загрузки:
getstatus.php
download.php
источник
.each()
для регистрации событий. просто скажи$('a.download').click()
setTimeout('getstatus()', 1000);
. Используйте fn напрямую:setTimeout(getstatus, 1000);
Я использую следующее для загрузки BLOB-объектов и отзыва URL-адреса объекта после загрузки. это работает в Chrome и Firefox!
после того, как диалоговое окно загрузки файла закрыто, окно возвращает ее фокус, так что происходит событие фокуса.
источник
На примере Элмера я подготовил собственное решение. После щелчка элементов с определенным классом загрузки это позволяет показывать пользовательское сообщение на экране. Я использовал фокус триггера, чтобы скрыть сообщение.
JavaScript
HTML
Теперь вы должны реализовать любой элемент для загрузки:
или
После каждого клика на загрузку вы увидите сообщение о создании вашего отчета, пожалуйста подождите ...
источник
Я написал простой класс JavaScript, который реализует технику, аналогичную описанной в бредовом ответе . Я надеюсь, что это может быть полезно для кого-то здесь. Проект GitHub называется response-monitor.js
По умолчанию он использует spin.js в качестве индикатора ожидания, но также предоставляет набор обратных вызовов для реализации пользовательского индикатора.
JQuery поддерживается, но не требуется.
Известные особенности
Пример использования
HTML
Клиент (простой JavaScript)
Клиент (JQuery)
Клиент с обратными вызовами (JQuery)
Сервер (PHP)
Дополнительные примеры можно найти в папке примеров в хранилище.
источник
Я очень поздно на вечеринку, но я поставлю это здесь, если кто-то еще хотел бы узнать мое решение:
У меня была настоящая борьба с этой конкретной проблемой, но я нашел жизнеспособное решение, используя iframes (я знаю, я знаю. Это ужасно, но это работает для простой проблемы, которая у меня была)
У меня была HTML-страница, которая запустила отдельный скрипт php, который сгенерировал файл, а затем загрузил его. На html-странице я использовал следующий jquery в html-заголовке (также необходимо включить библиотеку jquery):
На your_download_script.php имейте следующее:
Чтобы разобраться в этом, jquery сначала запускает ваш php-скрипт в iframe. Iframe загружается после создания файла. Затем jquery снова запускает скрипт с переменной запроса, сообщающей скрипту о загрузке файла.
Причина, по которой вы не можете выполнять загрузку и генерацию файлов одновременно, связана с функцией php header (). Если вы используете header (), вы изменяете скрипт на что-то иное, чем веб-страница, и jquery никогда не распознает загружаемый скрипт как «загруженный». Я знаю, что это не обязательно обнаруживает, когда браузер получает файл, но ваша проблема звучит похоже на мою.
источник
Если вы создаете потоковую передачу файла, который вы генерируете динамически, а также внедрили библиотеку обмена сообщениями между серверами в реальном времени, вы можете довольно легко предупредить вашего клиента.
Библиотека обмена сообщениями между серверами, которую я люблю и рекомендую, - Socket.io (через Node.js). После того, как ваш серверный скрипт завершит генерацию файла, который передается для загрузки, ваша последняя строка в этом скрипте может отправить сообщение в Socket.io, которое отправит уведомление клиенту. На клиенте Socket.io прослушивает входящие сообщения, отправленные с сервера, и позволяет вам действовать с ними. Преимущество использования этого метода перед другими заключается в том, что вы можете обнаружить «истинное» событие завершения после завершения потоковой передачи.
Например, вы можете отобразить индикатор занятости после нажатия на ссылку для скачивания, отправить файл в потоковом режиме, отправить сообщение на сервер Socket.io в последней строке вашего скрипта потоковой передачи, прослушать уведомление клиента, получить уведомление и обновите свой интерфейс, скрыв индикатор занятости.
Я понимаю, что большинство людей, читающих ответы на этот вопрос, могут не иметь такой установки, но я использовал это точное решение с большим эффектом в своих собственных проектах, и оно прекрасно работает.
Socket.io невероятно прост в установке и использовании. Смотрите больше: http://socket.io/
источник
"Как определить, когда браузер получает загрузку файла?"
Я столкнулся с той же проблемой с этим конфигом:
struts 1.2.9
jquery-1.3.2.
jquery-ui-1.7.1. пользовательский
IE 11
java 5
Мое решение с cookie:
- Клиентская сторона:
при отправке формы вызовите функцию javascript, чтобы скрыть страницу и загрузить ожидающий счетчик
Затем вызовите функцию, которая будет каждые 500 мс проверять, приходит ли файл cookie с сервера.
Если cookie-файл найден, прекратите проверку каждые 500 мс, прекратите использование cookie-файла и вызовите свою функцию, чтобы вернуться на свою страницу и удалить ожидающий счетчик ( removeWaitingSpinner () ). Важно, чтобы срок действия файла cookie истек, если вы хотите снова загрузить другой файл!
- Серверная сторона:
в конце вашего серверного процесса добавьте куки-файл в ответ. Этот файл cookie будет отправлен клиенту, когда ваш файл будет готов к загрузке.
Я надеюсь помочь кому-то!
источник
Когда пользователь запускает генерацию файла, вы можете просто назначить уникальный идентификатор для этой «загрузки» и отправить пользователя на страницу, которая обновляется (или проверяется с помощью AJAX) каждые несколько секунд. Как только файл будет завершен, сохраните его под тем же уникальным идентификатором и ...
Тогда вы можете пропустить весь беспорядок iframe / wait / browserwindow, но при этом получить действительно элегантное решение.
источник
Если вы не хотите генерировать и хранить файл на сервере, готовы ли вы сохранить статус, например, файл в процессе, файл завершен? Ваша страница ожидания может опросить сервер, чтобы узнать, когда генерация файла завершена. Вы не могли бы знать наверняка, что браузер начал загрузку, но у вас будет некоторая уверенность.
источник
У меня была точно такая же проблема. Моим решением было использовать временные файлы, так как я уже генерировал кучу временных файлов. Форма представляется вместе с:
В конце сценария, который генерирует файл, который я имею:
Это вызовет событие загрузки в iframe. Затем сообщение ожидания закрывается и начинается загрузка файла. Протестировано на IE7 и Firefox.
источник
По моему опыту, есть два способа справиться с этим:
источник
Привет, я знаю, что тема старая, но я оставляю решение, которое я видел в другом месте, и оно работало:
Вы можете использовать это:
источник
Если у вас есть загруженный файл, который сохраняется, а не находится в документе, невозможно определить, когда загрузка завершена, поскольку это не входит в область действия текущего документа, а представляет собой отдельный процесс в браузере.
источник
Вопрос заключается в том, чтобы во время генерации файла был индикатор ожидания, а затем, когда файл загружается, он возвращается в нормальное состояние. Мне нравится делать это, используя скрытый iFrame и перехватывая событие onload фрейма, чтобы сообщить моей странице, когда начинается загрузка. НО onload не запускается в IE при загрузке файлов (как с токеном заголовка вложения). Опрос сервера работает, но мне не нравится дополнительная сложность. Итак, вот что я делаю:
Отказ от ответственности, не делайте этого на загруженном сайте, потому что кеширование может сложиться. Но на самом деле, если ваши сайты, которые заняты длительным процессом, в любом случае лишат вас потоков.
Вот как выглядит код, и это все, что вам действительно нужно.
источник
Быстрое решение, если вы хотите отображать только сообщение или gif-загрузчик до тех пор, пока не отобразится диалоговое окно загрузки, - это поместить сообщение в скрытый контейнер, и когда вы нажимаете кнопку, генерирующую файл для загрузки, вы делаете контейнер видимым. Затем используйте jquery или javascript, чтобы перехватить событие focusout кнопки, чтобы скрыть контейнер, содержащий сообщение.
источник
Если Xmlhttprequest с blob не является опцией, вы можете открыть свой файл в новом окне и проверить, заполняются ли элементы eny в этом теле окна с интервалом.
источник
Этот пример Java / Spring определяет конец загрузки, после чего скрывает индикатор «Загрузка ...».
Подход: на стороне JS установите Cookie с максимальным сроком действия 2 мин и опрашивайте каждую секунду для истечения срока действия куки . Затем на стороне сервера переопределяет это печенье с ранее сроком действия - завершением процесса сервера. Как только в опросе JS обнаруживается истечение срока действия cookie, «Загрузка ...» скрывается.
JS Side
Серверная часть Java / Spring
источник
myCookie.setPath("/"); response.addCookie(myCookie);
Primefaces также использует опрос cookie
https://github.com/primefaces/primefaces/blob/32bb00299d00e50b2cba430638468a4145f4edb0/src/main/resources/META-INF/resources/primefaces/core/core.js#L458
источник
Создайте iframe при нажатии кнопки / ссылки и добавьте его в тело.
Создайте iframe с задержкой и удалите его после загрузки.
источник