#php #ajax #file-upload #progress-bar
#php #ajax #загрузка файла #индикатор выполнения
Вопрос:
До сих пор я выяснял, КАК загружать файлы асинхронно с помощью Ajax и PHP, никаких проблем нет. Но я хочу получить процент от файла, который уже загружен, по мере его загрузки, и, после нескольких часов исследований, я не могу найти хороший способ сделать это без обмана.
реализации некоторые, которые я видел, использовали Flash для загрузки, и получение процента во Flash, по-видимому, довольно распространено, но я бы хотел избежать этого, если смогу.
Есть идеи?
Ответ №1:
Основная проблема заключается в том, что RFC 1867, спецификация для загрузки файлов по HTTP с помощью multipart/form-data
типа MIME, не предоставляет никакого метода для обеспечения прогресса загрузки файла.
Загрузка файла на самом деле — это просто необычная форма отправки. CGI-скрипты, PHP и все другие веб-технологии, которые полагаются на интерфейсный веб-сервер для первого принятия запроса, могут фактически не начать выполняться до завершения всей загрузки. Это означает, что они обычно даже не могут знать, когда началась загрузка, только когда она была завершена.
Новые версии расширения APC PHP включают в себя обходной путь для этой проблемы, который выполняет некоторый уровень черной магии, позволяющий ему узнавать о загрузках раньше. Однако это работает только как часть mod_php. Разработчики, похоже, не планируют поддерживать его в FastCGI.
Другим вариантом на стороне сервера было бы расширение PECL «uploadprogress». Я не совсем уверен, какую черную магию он использует. Источник предполагает, что он фактически подключается к обработке multipart
частей MIME. (Это предполагает, что по крайней мере некоторые SAPIs передают данные формы в PHP по мере их загрузки клиентом. Я знаю, что по крайней мере некоторые серверы FastCGI буферизуют весь запрос перед его передачей, так что у вас это может не сработать. YMMV.)
Оба этих параметра предназначены для обычной загрузки файла. Ajax — или, скорее, XMLHttpRequest — не поддерживает операции загрузки файла. Большинство обходных путей в этой области включают создание iframe и отправку формы там, и это также подразумевает работу на стороне клиента кем-то другим. Если вы собираетесь пройти этот уровень прыжков с обручем, вы также можете использовать один из современных виджетов загрузки файлов.
Лично я использую Plupload, виджет Javascript, который может работать со всеми любимой библиотекой Javascript, jQuery. Некоторые другие клянутся Uploadify. Несмотря на это, оба этих виджета обеспечивают высокую степень обратной связи пользователя с ходом загрузки. Вероятно, вам будет проще реализовать их, чем APC или uploadprogress, и их преимущество в том, что они создаются и тщательно тестируются другими людьми.
Plupload поддерживает несколько движков загрузки, включая HTML5, Gears, Flash, Silverlight, oldschool HTML4 и другие. Используя HTML5, Flash и Silverlight, вы практически только что охватили 100% своей аудитории. Это также позволяет вам подписываться на события и заставлять ваш собственный код творить чудеса. Например, если вам нужна информация о ходе загрузки файла на стороне сервера, вы можете попросить клиента регулярно отправлять обновления в другой скрипт. Это было бы полезно, если ваши клиенты регулярно загружают огромные файлы и вы хотите знать об этом в режиме реального времени.
tl; dr: Загрузка затруднена, давайте перейдем на сторону клиента!
Комментарии:
1. Что ж, тогда, похоже, помимо хакерских APC и uploadprogress (которыми я занимался последние пару часов), Flash — это единственный вариант на некоторое время (пока HTML5 не воцарится безраздельно).
2. @altrier, к сожалению, это правда. У Flash действительно есть свои применения.
Ответ №2:
Да, мне тоже не нравится этот «читерский» метод, на мой взгляд, лучший метод — использовать APC и его метод, apc_fetch
Использование ajax для создания apc_fetch с уникальным ключом, определяющим загрузку, вернет то, что вам нужно.. т.е. загруженные байты / общее количество байт.
Затем просто создайте индикатор выполнения с помощью javascript.
Я слышал, что chrome и safari не позволяют выполнять вызовы ajax во время последующей загрузки, обходной путь включает использование iframe для выполнения вызовов с идентификатором apc.