У меня проблема с отправкой файла на серверный PHP-скрипт с использованием ajax-функции jQuery. Можно получить список файлов, $('#fileinput').attr('files')
но как можно отправить эти данные на сервер? Результирующий array ( $_POST
) на php-скрипте на стороне сервера равен 0 ( NULL
) при использовании file-input.
Я знаю, что это возможно (хотя до сих пор я не нашел решений jQuery, только код Prototye ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ) ).
Это кажется относительно новым, поэтому, пожалуйста, не упоминайте, что загрузка файлов будет невозможна через XHR / Ajax, потому что это определенно работает.
Мне нужна функциональность в Safari 5, FF и Chrome были бы хороши, но не обязательны.
Мой код сейчас:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
$(':file')
для выбора всех входных файлов. Это немного проще.Ответы:
Начиная с Safari 5 / Firefox 4, проще всего использовать
FormData
класс:Итак, теперь у вас есть
FormData
объект, готовый к отправке вместе с XMLHttpRequest.Крайне важно, чтобы вы установили
contentType
опциюfalse
, заставляя jQuery не добавлятьContent-Type
заголовок для вас, в противном случае строка границы будет отсутствовать в нем. Кроме того, вы должны оставитьprocessData
флаг установленным в false, иначе jQuery попытается преобразовать ваш файлFormData
в строку, что не удастся.Теперь вы можете получить файл в PHP, используя:
(Существует только один файл,
file-0
если только вы не указалиmultiple
атрибут на входе файла, в этом случае номера будут увеличиваться с каждым файлом.)Использование эмуляции FormData для старых браузеров
Создать FormData из существующей формы
Вместо ручной итерации файлов, объект FormData также может быть создан с содержимым существующего объекта формы:
Используйте собственный массив PHP вместо счетчика
Просто назовите элементы вашего файла одинаково и оканчивайте имя в скобках:
$_FILES['file']
затем будет массив, содержащий поля загрузки файла для каждого загруженного файла. Я на самом деле рекомендую это поверх моего первоначального решения, так как его проще повторить.источник
data.fake
и установитьcontentType
свойство вручную, а также переопределить xhr для использованияsendAsBinary()
.jQuery
ниFormData
класс, ни вопрос и задаете мне вопрос в контексте, касающемся jQuery, и ответ, касающийся использования FormData? Извините, но я не думаю, что могу помочь вам там ...application/x-www-form-urlencoded
. Есть ли способ использоватьmultipart/form-data
вместо этого?multipart/form-data
. Использованиеapplication/x-www-form-urlencoded
не будет работать.Просто хотел добавить немного к отличному ответу Рафаэля. Вот как заставить PHP производить то же самое
$_FILES
, независимо от того, используете ли вы JavaScript для отправки.HTML-форма:
PHP производит это
$_FILES
, когда отправлено без JavaScript:Если вы делаете прогрессивное улучшение, используя Raphael JS для отправки файлов ...
... так
$_FILES
выглядит массив PHP после использования этого JavaScript для отправки:Это хороший массив, и на самом деле это то, во что превращаются некоторые люди
$_FILES
, но я считаю, что с ним можно работать$_FILES
независимо от того, использовался ли JavaScript для отправки. Итак, вот некоторые незначительные изменения в JS:(14 апреля 2017 г., редактирование: я удалил элемент формы из конструктора FormData () - это исправило этот код в Safari.)
Этот код делает две вещи.
input
атрибут name автоматически, делая HTML более удобным для сопровождения. Теперь, покаform
есть класс putImages, все остальное решается автоматически. То естьinput
не нужно иметь никакого специального имени.С учетом этих изменений отправка с использованием JavaScript теперь создает точно такой же
$_FILES
массив, что и отправка с простым HTML.источник
Посмотри на мой код, он делает всю работу за меня
источник
Я только что построил эту функцию на основе информации, которую я прочитал.
Используйте это как использование
.serialize()
, вместо этого просто положите.serializefiles();
.Работаю здесь в моих тестах.
источник
var data = $("#avatar-form").serializefiles();
отправкой через параметр данных ajax и анализ с помощью выраженного огромного:form.parse(req, function(err, fields, files){
спасибо за этот фрагмент кода :)Если ваша форма определена в вашем HTML, проще передать форму в конструктор, чем перебирать и добавлять изображения.
источник
Ответ Девина Венейбла был близок к тому, что я хотел, но я хотел, чтобы он работал с несколькими формами и использовал действие, уже указанное в форме, чтобы каждый файл располагался в нужном месте.
Я также хотел использовать метод on () jQuery, чтобы избежать использования .ready ().
Это привело меня к этому: (замените formSelector на ваш селектор jQuery)
источник
В настоящее время вам даже не нужна таблица поддержки API выборки jQuery :)
источник
fetch
совместимость смотрите: developer.mozilla.org/en-US/docs/Web/API/…:-|
Класс FormData работает, однако в iOS Safari (по крайней мере, на iPhone) я не смог использовать решение Рафаэля Швейкера как есть.
У Mozilla Dev есть хорошая страница по манипулированию объектами FormData .
Итак, добавьте пустую форму где-нибудь на вашей странице, указав enctype:
Затем создайте объект FormData как:
и действуйте как в коде Рафаэля .
источник
Одна проблема, с которой я столкнулся сегодня, я думаю, стоит упомянуть, связанную с этой проблемой: если URL для вызова ajax перенаправлен, тогда заголовок для типа содержимого: 'multipart / form-data' может быть потерян.
Например, я писал на http://server.com/context?param=x
На вкладке сети Chrome я увидел правильный многокомпонентный заголовок для этого запроса, а затем перенаправил 302 на http://server.com/context/?param=x (обратите внимание на косую черту после контекста)
Во время перенаправления многочастный заголовок был потерян. Убедитесь, что запросы не перенаправляются, если эти решения не работают для вас.
источник
Все решения, представленные выше, выглядят хорошо и элегантно, но объект FormData () не ожидает какого-либо параметра, но использует метод append () после его создания, например, как написано выше:
formData.append (val.name, val.value);
источник
Если входные данные файла
name
указывают на массив и флагиmultiple
, и вы анализируете всеform
вместеFormData
, нет необходимости повторятьappend()
входные файлы итеративно .FormData
будет автоматически обрабатывать несколько файлов.Обратите внимание, что используется обычный
button type="button"
, а неtype="submit"
. Это показывает, что нет никакой зависимости от использования,submit
чтобы получить эту функциональность.Результирующая
$_FILES
запись выглядит так в инструментах разработчика Chrome:Примечание. В некоторых случаях при загрузке в виде одного файла некоторые изображения будут загружаться очень хорошо, но при загрузке в виде набора из нескольких файлов произойдет сбой. Симптом заключается в том, что отчеты PHP пустые
$_POST
и$_FILES
без AJAX выдают какие-либо ошибки. Проблема возникает с Chrome 75.0.3770.100 и PHP 7.0. Похоже, это происходит только с 1 из нескольких десятков изображений в моем тестовом наборе.источник
Более старые версии IE не поддерживают FormData (полный список поддержки браузера для FormData находится здесь: https://developer.mozilla.org/en-US/docs/Web/API/FormData ).
Либо вы можете использовать плагин jquery (например, http://malsup.com/jquery/form/#code-samples ), либо вы можете использовать решение на основе IFrame для публикации данных из нескольких форм через ajax: https: // developer. mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
источник
PHP
JQuery и форма HTML
источник
источник