FormData
XMLHttpRequest 2 добавляет поддержку для нового интерфейса FormData. Объекты FormData позволяют вам легко конструировать наборы пар ключ-значение, представляющие поля формы и их значения, которые в дальнейшем можно отправить с помощью метода send() (en-US) .
FormData использует такой же формат на выходе, как если бы мы отправляли обыкновенную форму с encoding установленным в «multipart/form-data».
Примечание: О деталях использования FormData можно прочитать в статье Использование объекта FormData (en-US) .
Конструктор
Создаёт объект FormData .
Методы
Добавляет новое значение существующего поля объекта FormData , либо создаёт его и присваивает значение.
Удаляет пару ключ-значение из объекта FormData .
Возвращает первое значение ассоциированное с переданным ключом из объекта FormData .
Возвращает массив всех значений ассоциированных с переданным ключом из объекта FormData .
Возвращает булево значение касательно наличия в объекте FormData конкретной пары ключ-значение.
Устанавливает новое значение для существующего ключа объекта FormData , или добавляет пару ключ-значение, если таковой не обнаружено в объекте.
Возвращает iterator , который позволяет пройтись по всем ключам для каждой пары «ключ-значение» , содержащимся внутри объекта FormData
Возвращает iterator который позволяет пройтись по всем парам «ключ-значение», содержащимся внутри объекта FormData
Возвращает iterator , который позволяет пройтись по всем значениям , содержащимся в объекте FormData
Примечание: Разница между FormData.set() и FormData.append() заключается в том, что если указанный ключ найден в объекте, FormData.set() перезапишет его новым значением, тогда как FormData.append() добавит новое значение в конец существующего. Смотрите дополнительные материалы с примерами.
Спецификация
| Specification |
|---|
| XMLHttpRequest Standard # interface-formdata |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
- XMLHTTPRequest
- Using XMLHttpRequest (en-US)
- Использование объектов FormData (en-US)
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 6 янв. 2024 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.
Form data что это
FormData — это интерфейс JavaScript, который позволяет работать с данными формы HTML. Он предоставляет удобный способ отправки данных на сервер без необходимости вручную создавать и настраивать объекты XMLHttpRequest.
Форма записи
Для создания объекта FormData используется конструктор FormData(), который можно вызвать без параметров или передать ему форму HTML в качестве параметра.
const formData = new FormData();
const form = document.querySelector('form'); const formData = new FormData(form);
Описание работы
FormData может быть использован в тех случаях, когда нужно отправить данные формы на сервер, включая текстовые поля, флажки, переключатели, файлы и т.д. Он также может быть использован для отправки данных в формате multipart/form-data, который используется при загрузке файлов на сервер.
Создание объекта FormData:
const formData = new FormData();
Добавление значений в форму:
formData.append('username', 'john'); formData.append('password', 'secret'); formData.append('avatar', fileInput.files[0]);
Работа с коллекцией значений:
formData.set('username', 'jane'); formData.delete('password'); formData.has('avatar'); // true formData.get('avatar'); // File object formData.getAll('username'); // ['john', 'jane']
Обход значений в форме:
for (const [key, value] of formData) < console.log(`$: $`); >
Заключение
FormData предоставляет удобный способ отправки данных формы на сервер в JavaScript. Он может быть использован для отправки текстовых полей, файлов и других типов данных. FormData также может быть использован для отправки данных в формате multipart/form-data, который используется при загрузке файлов на сервер. Использование FormData значительно расширяет возможности JavaScript и позволяет создавать интерактивные веб-приложения.
FormData
В этой главе речь пойдёт об отправке HTML-форм: с файлами и без, с дополнительными полями и так далее. Объекты FormData помогут нам с этим. Как вы, наверняка, догадались по его названию, это объект, представляющий данные HTML формы.
let formData = new FormData([form]);
Если передать в конструктор элемент HTML-формы form , то создаваемый объект автоматически прочитает из неё поля.
Его особенность заключается в том, что методы для работы с сетью, например fetch , позволяют указать объект FormData в свойстве тела запроса body .
Он будет соответствующим образом закодирован и отправлен с заголовком Content-Type: multipart/form-data .
То есть, для сервера это выглядит как обычная отправка формы.
Отправка простой формы
Давайте сначала отправим простую форму.
Как вы видите, код очень компактный:
В этом примере серверный код не представлен, он за рамками этой статьи, он принимает POST-запрос с данными формы и отвечает сообщением «Пользователь сохранён».
Методы объекта FormData
С помощью указанных ниже методов мы можем изменять поля в объекте FormData :
- formData.append(name, value) – добавляет к объекту поле с именем name и значением value ,
- formData.append(name, blob, fileName) – добавляет поле, как будто в форме имеется элемент , третий аргумент fileName устанавливает имя файла (не имя поля формы), как будто это имя из файловой системы пользователя,
- formData.delete(name) – удаляет поле с заданным именем name ,
- formData.get(name) – получает значение поля с именем name ,
- formData.has(name) – если существует поле с именем name , то возвращает true , иначе false
Технически форма может иметь много полей с одним и тем же именем name , поэтому несколько вызовов append добавят несколько полей с одинаковыми именами.
Ещё существует метод set , его синтаксис такой же, как у append . Разница в том, что .set удаляет все уже имеющиеся поля с именем name и только затем добавляет новое. То есть этот метод гарантирует, что будет существовать только одно поле с именем name , в остальном он аналогичен .append :
- formData.set(name, value) ,
- formData.set(name, blob, fileName) .
Поля объекта formData можно перебирать, используя цикл for..of :
let formData = new FormData(); formData.append('key1', 'value1'); formData.append('key2', 'value2'); // Список пар ключ/значение for(let [name, value] of formData) < alert(`$= $`); // key1=value1, потом key2=value2 >
Отправка формы с файлом
Объекты FormData всегда отсылаются с заголовком Content-Type: multipart/form-data , этот способ кодировки позволяет отсылать файлы. Таким образом, поля тоже отправляются, как это и происходит в случае обычной формы.
Пример такой формы:
Картинка:
Отправка формы с Blob-данными
Ранее в главе Fetch мы видели, что очень легко отправить динамически сгенерированные бинарные данные в формате Blob . Мы можем явно передать её в параметр body запроса fetch .
Но на практике бывает удобнее отправлять изображение не отдельно, а в составе формы, добавив дополнительные поля для имени и другие метаданные.
Кроме того, серверы часто настроены на приём именно форм, а не просто бинарных данных.
В примере ниже посылается изображение из и ещё несколько полей, как форма, используя FormData :
Пожалуйста, обратите внимание на то, как добавляется изображение Blob :
formData.append("image", imageBlob, "image.png");
Это как если бы в форме был элемент и пользователь прикрепил бы файл с именем «image.png» (3-й аргумент) и данными imageBlob (2-й аргумент) из своей файловой системы.
Сервер прочитает и данные и файл, точно так же, как если бы это была обычная отправка формы.
Итого
Объекты FormData используются, чтобы взять данные из HTML-формы и отправить их с помощью fetch или другого метода для работы с сетью.
Мы можем создать такой объект уже с данными, передав в конструктор HTML-форму – new FormData(form) , или же можно создать объект вообще без формы и затем добавить к нему поля с помощью методов:
- formData.append(name, value)
- formData.append(name, blob, fileName)
- formData.set(name, value)
- formData.set(name, blob, fileName)
Отметим две особенности:
- Метод set удаляет предыдущие поля с таким же именем, а append – нет. В этом их единственное отличие.
- Чтобы послать файл, нужно использовать синтаксис с тремя аргументами, в качестве третьего как раз указывается имя файла, которое обычно, при , берётся из файловой системы.
- formData.delete(name)
- formData.get(name)
- formData.has(name)
Кроссбраузерная отправка формы с файлом или как переписать весь отправщик несколько раз после тестирования в IE
Задача: отправка и обработка файлов с помощью FormData и FileReader в форме со всеми возможными полями и пересылкой дополнительных параметров для каждого поля c объединением всех данных формы (кроме файлов и системных полей) в общий массив.
Поддержка: все современные браузеры, IE 10+.
Плагины: jquery-2.1.4

Для начала разберемся, что же такое FormData
Formdata — тип данных в рамках технологии XHR2, данные в нем хранятся в виде пар ключ / значение.
new Formdata () — это конструктор для создания объекта FormData.

FormData имеет множество методов для полноценной работы с ней, таких как:
- .get() — возвращает данные по ключу;
- .getAll() — возвращает массив всех значений, ассоциированных с этим ключом;
- .has() — возвращает булевое значение касательно наличия объекта;
- .set() — добавляет значение к уже существующему ключу и, если его нет, создает его;
- .append() — создает новую пару ключ / значение;
- .delete() — удаляет объект по ключу;
- .forEach() — на нем остановимся подробнее:
Главная проблема FormData заключается в Internet explorer (как всегда), а вернее, в его поддержке. Из всех методов, которые есть в FormData, Internet explorer поддерживает только append(), что уничтожает всю простоту использования. Следовательно, мы не можем собрать форму с помощью простого вызова конструктора и последующего изменения данных в ней, и придется это делать вручную:
- Получим все данные формы через serializeArray(), переберем, проверим их на пустоту и, вместе с заголовком (data-title), если это не системное поле (type=”hidden”), занесем в ассоциативный массив, отдельный для каждого поля, а далее добавим в наш массив для данных формы.
- Системные поля мы сразу добавляем методом append() в FormData.
Теперь познакомимся с FileReader
FileReader — это объект, который позволяет веб-приложениям асинхронно читать содержимое файлов (или буферы данных), хранящиеся на компьютере пользователя, используя объекты File или Blob, с помощью которых задается файл или данные для чтения.
С его помощью мы будем отслеживать загрузку файлов на клиенте, формировать список загруженных файлов и выводить для них прогресс бар.
Теперь к самой задаче
Форма, которую мы будет пересылать:
Для удобства пользователей предоставим им возможность добавления сразу большого количества файлов. С этой целью укажем в поле name значение file[] и атрибут multiple, с ограничением только картинки accept=«image».
Для пользователей также будем выводить список файлов, которые они загрузили с раздельным progress bar-ом для каждого файла и возможностью удаления перед отправкой. И тут мы столкнулись с проблемой. Дело в том, что fileList (массив загруженных файлов) у нашего input предназначен только для чтения, и удалить только выбранный пользователем файл мы не можем. Так что было решено перед отправкой на сервер сверять список, который уже сформировал пользователь, с тем что уже загружено. И при совпадении со списком файл будет добавляться в FormData.
1) Создаем саму функцию отправки через ajax:
var form = form; //текущая форма function formSend(formObject, form) < $.ajax(< type: "POST", url: 'form-handler.php', dataType: 'json', contentType: false, processData: false, data: formObject, success: function() < $(form).trigger('reset'); //при успешной отправке сбрасываем форму в дефолтное состояние alert('Success'); >>); >;
2) Создаем функцию сборки формы:
function formData_assembly(form) < var formSendAll = new FormData(), //создаем объект FormData form_arr = $(form).find(':input,select,textarea').serializeArray(), //собираем все данные с формы без файлов formdata = <>; //ассациативный массив для хранения данных с формы for (var i = 0; i < form_arr.length; i++) < if (form_arr[i].value.length >0) < //перебераем массив с данными формы и проверяем на заполненность var current_input = $(form).find('input[name=' + form_arr[i].name + '],select[name=' + form_arr[i].name + '],textarea[name=' + form_arr[i].name + ']'), value_arr = <>; // новые массив с данными каждого поля + заголовок var title = $(current_input).attr('data-title'); //заголовок поля if ($(current_input).attr('type') != 'hidden') < //проверяем не является ли поле системным value_arr['value'] = form_arr[i].value; value_arr['title'] = title; formdata[form_arr[i].name] = value_arr; >else < formSendAll.append(form_arr[i].name, form_arr[i].value); //системные поля пересылаем отдельно от общей формы >> > formdata = JSON.stringify(formdata); formSendAll.append('formData', formdata); // добавляем все поля в formdata // file if ($(form).find('input[type=file]').hasClass('js_file_check')) < //проверяем есть ли input type file для пересылки var current_input = $(form).find('input[type=file]'); if ($(current_input).val().length >0) < //проверяем на заполненность $('.js_file_list li').each(function() < var list_file_name = $(this).find('span').text(); for (var k = 0; k < $(current_input)[0].files.length; k++) < if (list_file_name == $(current_input)[0].files[k].name) < //сверяем список выбранных файлов для загрузки formSendAll.append($(current_input).attr('name'), $(current_input)[0].files[k]); // добавляем только те что остались в списке >> >) > > formSend(formSendAll, form); > formData_assembly(form);
3) Оборачиваем все это в функцию для удобного вызова по событию:
function submit_function(form)
4) Вешаем функцию на событие клика на кнопку отправки формы:
$('.js_btn_submit').click(function (e) < e.preventDefault(); var current_form = $(this).closest('form');//Текущая форма submit_function(current_form); >)
Теперь у нас есть полноценный отправщик формы, осталось только написать обработчик для файлов.
1) Создадим функцию отслеживания состояния input type=file:
function checkFile() < var inputs = document.getElementsByClassName('js_file_check'); for (var i = 0; i < inputs.length; i++) < inputs[i].addEventListener('change', handleFileSelect, false); >> checkFile();
2) Напишем обработчик ошибок:
var reader; function abortRead() < reader.abort(); >function errorHandler(evt) < switch (evt.target.error.code) < case evt.target.error.NOT_FOUND_ERR: alert('File Not Found!'); break; case evt.target.error.NOT_READABLE_ERR: alert('File is not readable'); break; case evt.target.error.ABORT_ERR: break; // noop default: alert('An error occurred reading this file.'); >; >
3) Напишем функцию для переборки файлов в fileList нашего input type=file:
function handleFileSelect(evt) < var thisInput = $(this); //input type file для множественных загрузок for (var i = 0; i < thisInput[0].files.length; i++) < //перебираем все загруженные файлы и запускаем обработчик для каждого reader_file(thisInput[0].files[i]); //добавляем обработчик для каждого файла >>
4) Теперь непосредственно сам обработчик:
5) Добавим возможность удаления файлов из списка:
$(document).on('click', '.js_file_remove', function() < var list_item = $(this).closest('li'); $(list_item).remove(); >);
6) Можем использовать наш отправщик, не забыв поднять локальный сервер: