Зачем использовать FormData при загрузке файла через AJAX? - PullRequest
3 голосов
/ 25 апреля 2019

У меня есть форма, в которую пользователь может загрузить файл:

<form enctype="multipart/form-data method="POST" id="cool-form-id">
    <input type="file" id="file" name="file">
</form>

Я пытаюсь загрузить файл из этой формы, используя запрос AJAX:

    $.ajax({
          url: '/path/to/upload/',
          data: $("#cool-form-id").serialize(),
          processData: false,
          contentType: false,
          type: 'POST',
          success: function(data) {
            alert(data)
          }
      });

Если я проверяю объект, полученный селектором $ ("# cool-form-id"), я вижу поле формы и ввода, где кто-то выбрал файл, но после serialize () этот ввод пропадает (другой ввод поля в этой форме сериализуются, как и ожидалось.)

      var formData = new FormData($("#cool-form-id")[0]);

      $.ajax({
          url: '/path/to/upload/',
          data: formData,
          processData: false,
          contentType: false,
          type: 'POST',
          success: function(data) {
            alert(data)
          }
      });

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

Большинство вопросов, касающихся FormData, не являются актуальными, и многие просто предоставляют рабочий пример.

Мне любопытно, может кто-нибудь пролить свет на любое или все из следующего:

1) Почему вы не можете сериализовать () данные формы для ввода типа «файл»?

2) Что FormData делает по-другому, что заставляет его работать в этом сценарии?

3) Является ли FormData единственным / лучшим вариантом для загрузки файла (если вы не хотите использовать iFrame)?

1 Ответ

5 голосов
/ 25 апреля 2019

Зачем использовать FormData при загрузке файла через AJAX?

Потому что вы не можете сделать это иначе (кроме взлома iframe)

1) Почему вы не можете сериализовать () данные формы для ввода типа «файл»?

Потому что:

  • Кодировка application / x-www-form-urlencoded не имеет собственного способа выражения файлов
  • value при вводе файла не дает содержимого файла

serialize можно переписать , чтобы, например, использовать API FileList для чтения файлов, а затем кодировать base64 в строку application / x-www-form-urlencoded (это может быть, но jQuery не сделал этого), и тогда любой код на стороне сервера, который считывает данные, должен был бы декодировать данные base64.

2) Что FormData делает по-другому, что заставляет его работать в этом сценарии?

Создает тело в формате multipart / form-data и читает файлы из файловых вводов.

3) Является ли FormData единственным / лучшим вариантом для загрузки файла (если вы не хотите использовать iFrame)?

Это единственный разумный вариант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...