Нужно ли использовать файл API inorder для получения типа ввода файла в методе jquery.post? [Дубликат]

Он может быть разрешен ниже простым кодом с помощью Stream и Try в AbacusUtil :

Stream.of(accounts).filter(a -> Try.call(a::isActive)).map(a -> Try.call(a::getNumber)).toSet();

Раскрытие информации : Я разработчик AbacusUtil.

486
задан Adexe Rivera 13 December 2016 в 17:17
поделиться

12 ответов

Начиная с Safari 5 / Firefox 4, проще всего использовать класс FormData:

var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
    data.append('file-'+i, file);
});

Итак, теперь у вас есть объект FormData, готовый к отправке вместе с XMLHttpRequest.

jQuery.ajax({
    url: 'php/upload.php',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    method: 'POST',
    type: 'POST', // For jQuery < 1.9
    success: function(data){
        alert(data);
    }
});

Обязательно установить параметр contentType на false, заставляя jQuery не добавлять к вам заголовок Content-Type, иначе пограничная строка будет отсутствовать. Кроме того, вы должны оставить флаг processData установленным как false, в противном случае jQuery попытается преобразовать ваш FormData в строку, которая потерпит неудачу.

Теперь вы можете получить файл на PHP, используя:

$_FILES['file-0']

(Существует только один файл, file-0, если вы не указали атрибут multiple на входе файла, и в этом случае числа будут увеличиваться с каждым файлом.)

Использование эмуляции FormData для старых браузеров

var opts = {
    url: 'php/upload.php',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    method: 'POST',
    type: 'POST', // For jQuery < 1.9
    success: function(data){
        alert(data);
    }
};
if(data.fake) {
    // Make sure no text encoding stuff is done by xhr
    opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; }
    opts.contentType = "multipart/form-data; boundary="+data.boundary;
    opts.data = data.toString();
}
jQuery.ajax(opts);

Создание FormData из существующей формы

Вместо ручного итерации файлов FormData объект также может быть создан с содержимым существующего объекта формы:

var data = new FormData(jQuery('form')[0]);

Использовать собственный массив PHP вместо счетчика

Просто назовите ваши файловые элементы одинаковыми и запустите имя в скобках:

jQuery.each(jQuery('#file')[0].files, function(i, file) {
    data.append('file[]', file);
});

$_FILES['file'] будет массивом, содержащим поля для загрузки файлов для каждого загруженного файла. Я действительно рекомендую это по сравнению с моим первоначальным решением, поскольку его проще перебирать.

770
ответ дан Raphael Schweikert 19 August 2018 в 14:58
поделиться
  • 1
    Кроме того, существует эмуляция FormData , которая упростит перенос этого решения в старые браузеры. Все, что вам нужно сделать, это проверить data.fake и установить свойство contentType вручную, а также переопределить xhr для использования sendAsBinary(). – Raphael Schweikert 24 August 2011 в 09:01
  • 2
    Таким образом, вы не используете jQuery или класс FormData, и вы спрашиваете меня в контексте вопроса, специфичного для jQuery, и ответа, специфичного для использования FormData? Извините, но я не думаю, что могу помочь вам там ... – Raphael Schweikert 19 April 2012 в 10:44
  • 3
    Это использует application/x-www-form-urlencoded. Есть ли способ использовать multipart/form-data вместо этого? – Timmmm 6 April 2013 в 21:43
  • 4
    @Timmmm Нет, он использует multipart/form-data. Использование application/x-www-form-urlencoded не сработает. – Raphael Schweikert 7 April 2013 в 09:57
  • 5
    @RoyiNamir Это только зарегистрировано в коде , я боюсь. – Raphael Schweikert 6 January 2014 в 20:30

Просто хотел добавить немного к большому ответу Рафаэля. Вот как получить PHP для создания того же $_FILES, независимо от того, используете ли вы JavaScript.

HTML-форма:

<form enctype="multipart/form-data" action="/test.php" 
method="post" class="putImages">
   <input name="media[]" type="file" multiple/>
   <input class="button" type="submit" alt="Upload" value="Upload" />
</form>

PHP создает это $_FILES, когда представленный без JavaScript:

Array
(
    [media] => Array
        (
            [name] => Array
                (
                    [0] => Galata_Tower.jpg
                    [1] => 518f.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpIQaOYo
                    [1] => /tmp/phpJQaOYo
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 258004
                    [1] => 127884
                )

        )

)

Если вы делаете прогрессивное повышение, используя JS Raphael для отправки файлов ...

var data = new FormData($('input[name^="media"]'));     
jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
    data.append(i, file);
});

$.ajax({
    type: ppiFormMethod,
    data: data,
    url: ppiFormActionURL,
    cache: false,
    contentType: false,
    processData: false,
    success: function(data){
        alert(data);
    }
});

... это то, что PHP $_FILES массив выглядит, после использования этого JavaScript для отправки:

Array
(
    [0] => Array
        (
            [name] => Galata_Tower.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpAQaOYo
            [error] => 0
            [size] => 258004
        )

    [1] => Array
        (
            [name] => 518f.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpBQaOYo
            [error] => 0
            [size] => 127884
        )

)

Это хороший массив, и на самом деле некоторые люди трансформируют $_FILES в, но я считаю полезным работать с тем же $_FILES , независимо от того, был ли JavaScript использован для отправки. Итак, вот некоторые незначительные изменения в JS:

// match anything not a [ or ]
regexp = /^[^[\]]+/;
var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );

// make files available
var data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
    data.append(fileInputName+'['+i+']', file);
});

(14 апреля 2017 г. edit: я удалил элемент формы из конструктора FormData (), который исправил этот код в Safari.)

Этот код выполняет две функции.

  1. Автоматически извлекает атрибут имени input, что делает HTML более удобным. Теперь, пока form имеет класс putImages, все остальное заботится автоматически. То есть, у input не должно быть специального имени.
  2. Формат массива, который представляет обычный HTML-код, воссоздается JavaScript в строке data.append. Обратите внимание на скобки.

С этими изменениями, отправляя с помощью JavaScript, теперь создается точно такой же массив $_FILES, что отправляется с простым HTML.

44
ответ дан ajmicek 19 August 2018 в 14:58
поделиться
  • 1
    Имел ту же проблему с Safari. Спасибо за подсказку! – medoingthings 4 August 2018 в 12:42

Посмотрите на мой код, он выполняет эту работу для меня

$( '#formId' )
  .submit( function( e ) {
    $.ajax( {
      url: 'FormSubmitUrl',
      type: 'POST',
      data: new FormData( this ),
      processData: false,
      contentType: false
    } );
    e.preventDefault();
  } );
37
ответ дан Asad Malik 19 August 2018 в 14:58
поделиться
  1. получить объект формы с помощью jquery-> $ ("# id") [0]
  2. data = new FormData ($ ("# id") [0]);
  3. ok, данные - ваши пожелания
-1
ответ дан Azik Abdullah 19 August 2018 в 14:58
поделиться
  • 1
    $ (& lt; # id & quot;) [0] возвращает сначала ни один пустой & lt; input type = & quot; файл & quot; / & GT; формы, как вы представляете всю форму, включая все & lt; input type = & quot; file & quot; / & GT; из этого? – Mohammad-Hossein Jamali 29 May 2015 в 06:47

Я только что создал эту функцию на основе некоторой информации, которую я прочитал.

Используйте ее, как с помощью .serialize(), вместо этого просто поставьте .serializefiles();. Работа в моих тестах.

//USAGE: $("#form").serializefiles();
(function($) {
$.fn.serializefiles = function() {
    var obj = $(this);
    /* ADD FILE TO PARAM AJAX */
    var formData = new FormData();
    $.each($(obj).find("input[type='file']"), function(i, tag) {
        $.each($(tag)[0].files, function(i, file) {
            formData.append(tag.name, file);
        });
    });
    var params = $(obj).serializeArray();
    $.each(params, function (i, val) {
        formData.append(val.name, val.value);
    });
    return formData;
};
})(jQuery);
43
ответ дан bfavaretto 19 August 2018 в 14:58
поделиться
  • 1
    Я пытался заставить эту работу работать, но, похоже, она не распознала функцию serializefiles () как функцию, несмотря на то, что это определение находится в верхней части страницы. – Fallenreaper 19 September 2012 в 16:09
  • 2
    это работает для меня просто отлично. получая данные с var data = $("#avatar-form").serializefiles();, отправляя это через параметр данных ajax и анализируя с помощью выраженного грозного: form.parse(req, function(err, fields, files){ благодарим вас за этот фрагмент кода :) – SchurigH 19 November 2013 в 23:53
  • 3
    это было сложно (y): D понравилось – sarath 18 May 2015 в 10:30

Класс FormData работает, однако в iOS Safari (по крайней мере, на iPhone) я не смог использовать решение Рафаэля Швайкерта как есть.

Mozilla Dev имеет приятную страницу on манипулируя объектами FormData .

Итак, добавьте пустую форму где-нибудь на вашей странице, указав enctype:

<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form>

Затем создайте объект FormData как:

var data = new FormData($("#fileinfo"));

и продолжайте, как в коде Рафаэля .

5
ответ дан Community 19 August 2018 в 14:58
поделиться
  • 1
    У меня возникла проблема с загрузкой jquery ajax, незаметно зависающей в Safari, и закончил тем, что сделал браузер условным $ ('form-name'). Submit () для Safari вместо загрузки ajax, которая работает в IE9 и FF18. Вероятно, это не идеальное решение для нескольких загрузок, но я делал это для одного файла в iframe из диалогового окна jquery, чтобы он работал нормально. – glyph 1 March 2013 в 23:17

Если ваша форма определена в вашем HTML, проще передать форму в конструктор, чем для итерации и добавления изображений.

$('#my-form').submit( function(e) {
    e.preventDefault();

    var data = new FormData(this); // <-- 'this' is your form element

    $.ajax({
            url: '/my_URL/',
            data: data,
            cache: false,
            contentType: false,
            processData: false,
            type: 'POST',     
            success: function(data){
            ...
21
ответ дан Devin Venable 19 August 2018 в 14:58
поделиться

Один из них, на который я столкнулся сегодня, думаю, стоит обратить внимание на эту проблему: если URL-адрес для вызова ajax перенаправлен, заголовок для типа контента: «multipart / form-data» может быть потерян.

Например, я отправлял сообщение в http://server.com/context?param=x

. На вкладке «Сеть» в Chrome я увидел правильный multipart заголовок для этого запроса, но затем перенаправление 302 на http://server.com/context/?param=x (обратите внимание на слэш после контекста)

Во время перенаправления multipart заголовок был потерян. Убедитесь, что запросы не перенаправляются, если эти решения не работают для вас.

0
ответ дан james 19 August 2018 в 14:58
поделиться

Старые версии IE не поддерживают FormData (Полный список поддержки браузера для FormData находится здесь: https://developer.mozilla.org/en-US/docs/Web/API/FormData ) .

Либо вы можете использовать плагин jquery (для ex, http://malsup.com/jquery/form/#code-samples ), либо вы можете использовать IFrame based решение для отправки данных многочастной формы через ajax: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

0
ответ дан sudip 19 August 2018 в 14:58
поделиться

Все вышеприведенные решения выглядят хорошо и элегантно, но объект FormData () не ожидает какого-либо параметра, но использует append () после его создания, как то, что было написано выше:

formData.append (val.name, val.value);

0
ответ дан szatti1489 19 August 2018 в 14:58
поделиться
0
ответ дан Alex Nikulin 31 October 2018 в 02:21
поделиться
5
ответ дан Community 31 October 2018 в 02:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: