Конвертация JS объекта в FormData: работа с файлами

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если нужно преобразовать объект JavaScript в FormData, можно извлечь пары ключ-значение и добавить их следующим образом:

JS
Скопировать код
const obj = { key1: 'value1', key2: 'value2' };
const formData = new FormData();

Object.entries(obj).forEach(([key, value]) => {
  formData.append(key, value);
});

Таким образом, каждое свойство объекта становится частью экземпляра FormData, словно мы пакуем вещи в чемодан перед поездкой.

Кинга Идем в IT: пошаговый план для смены профессии

Обработка различных типов данных

Преобразование вложенных объектов и массивов

Если включены вложенные объекты или массивы в вашем объекте JavaScript, следует использовать рекуррентный подход:

JS
Скопировать код
function serialize(data, parentKey, formData = new FormData()) {
  Object.entries(data).forEach(([key, value]) => {
    if (value instanceof File) {
      formData.append(parentKey ? `${parentKey}[${key}]` : key, value);
    } else if (typeof value === 'object' && !(value instanceof Date)) {
      serialize(value, parentKey ? `${parentKey}[${key}]` : key, formData);
    } else {
      formData.append(parentKey ? `${parentKey}[${key}]` : key, value);
    }
  });
  return formData;
}

const obj = { user: { name: 'Алиса', avatar: FileObject } };
const formData = serialize(obj);

Исключение ненужных свойств

Если есть свойства, которые не должны быть включены в FormData, можно использовать список исключений:

JS
Скопировать код
const ignoreList = ['secret', 'deprecated'];

Object.entries(obj).forEach(([key, value]) => {
  if (!ignoreList.includes(key)) {
    formData.append(key, value);
  }
});

Особые особенности работы с файлами

С файлами необходимо обращаться особенно осторожно, передавая их напрямую в FormData:

JS
Скопировать код
if (value instanceof File) {
  formData.append(key, value, value.name);
}

Продвинутые методы

Преимущества ES6

Можно использовать возможности ES6 для более элегантной преобразования:

JS
Скопировать код
const obj = { key1: 'value1', key2: 'value2' };
const formData = Object.keys(obj).reduce((fd, key) => (fd.append(key, obj[key]), fd), new FormData());

Глубокая рекурсия для вложенных объектов

Для обработки сложных структур объектов вносите рекурсию:

JS
Скопировать код
const convertToFormData = (obj, fd = new FormData(), prevKey = null) => {
  Object.entries(obj).forEach(([key, value]) => {
    const fieldName = prevKey ? `${prevKey}[${key}]` : key;
    if (value instanceof Object && !(value instanceof File || value instanceof Date)) {
      convertToFormData(value, fd, fieldName);
    } else {
      fd.append(fieldName, value);
    }
  });
  return fd;
};

При отправке данных с помощью $.ajax() в jQuery установите параметры processData и contentType в false:

JS
Скопировать код
$.ajax({
  url: '/target-url',
  type: 'POST',
  data: formData,
  processData: false,
  contentType: false,
  success: function(data) {
    console.log('Загрузка прошла успешно!');
  }
});

Визуализация

Считайте JS-объект специей чемоданом для путешествия:

Markdown
Скопировать код
JS Object (🧳): { name: 'Алиса', age: 25, city: 'Страна чудес' }

Мы поочерёдно упаковываем каждый элемент в форму:

JS
Скопировать код
let formData = new FormData();
formData.append('name', 'Алиса');
formData.append('age', 25);
formData.append('city', 'Страна чудес');

Проверим содержимое успешно упакованной формы:

Markdown
Скопировать код
Form Data (📬): 
- пакет 'name': 'Алиса'
- пакет 'age': 25
- пакет 'city': 'Страна чудес'

Теперь все готово к отправке!

Обработка ошибок и ответа сервера

Валидация на сервере

Следует уделять особое внимание безопасности – обязательно проверяйте содержимое FormData на серверной стороне:

php
Скопировать код
if ($_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
  // Файл загружен без ошибок
} else {
  // Необходимо предпринять действия по устранению ошибки загрузки
}

Обработка ответа клиентом

Воспользуйтесь и требуйте от jQuery для приема серверных ответов и обработки возможных ошибок:

JS
Скопировать код
$.ajax(/*...*/).done(function(data) {
  console.log('Ответ сервера:', data);
}).fail(function(jqXHR, textStatus) {
  console.error('Ошибка запроса:', textStatus);
});

Совместимость с различными браузерами

Гарантируйте совместимость вашего кода с IE11 и более новыми версиями браузеров, проводя тщательное тестирование.

Полезные материалы

  1. FormData – Веб API | MDN — подробное описание работы с FormData.
  2. Использование объектов FormData – Веб API | MDN — руководство по использованию FormData в сочетании с XMLHttpRequest.
  3. FormData — обзор API Fetch и FormData.
  4. HTML Элементы форм — руководство по элементам форм HTML.
  5. Использование Fetch | CSS-Tricks — статья о том, как применять fetch.