Ответ
multipart/form-data — это тип содержимого (Content-Type) для кодирования данных HTML-форм при отправке через HTTP. Он позволяет передавать в одном запросе как текстовые поля, так и бинарные файлы (изображения, документы и т.д.).
Как это работает:
Запрос разбивается на несколько «частей» (parts), разделённых уникальной строкой-границей (boundary). Каждая часть содержит свои заголовки (например, Content-Disposition с именем поля) и тело с данными.
Пример отправки файла и текста в Flutter/Dart с пакетом http:
import 'package:http/http.dart' as http;
Future<void> uploadImage(String imagePath, String description) async {
var request = http.MultipartRequest(
'POST',
Uri.parse('https://api.example.com/upload'),
);
// Добавляем файл
request.files.add(
await http.MultipartFile.fromPath(
'image', // Имя поля формы
imagePath,
contentType: MediaType('image', 'jpeg'),
),
);
// Добавляем текстовое поле
request.fields['description'] = description;
try {
final response = await request.send();
if (response.statusCode == 200) {
print('Файл успешно загружен');
} else {
print('Ошибка: ${response.statusCode}');
}
} catch (e) {
print('Ошибка сети: $e');
}
}
Когда использовать:
- Загрузка файлов на сервер.
- Отправка форм, содержащих смешанные данные (текст + файлы).
- Реализация API, аналогичного поведению HTML-формы с атрибутом
enctype="multipart/form-data".
Ответ 18+ 🔞
А, ну это же классика, ёпта! multipart/form-data — это такой специальный контент-тайп, когда тебе надо отправить на сервер не просто текстовую записку, а целый набор: и текст, и файлы в одном флаконе. Представь, будто ты не просто пишешь письмо, а прикладываешь к нему фотку своей собаки и квитанцию за квартиру — вот это оно и есть.
Как эта штука устроена, если без заумностей: Запрос делится на куски, как торт на дне рождения. Между кусками — уникальная разделительная полоска (boundary). В каждом куске свои метаданные (типа, «это фотка, зовут Барсик») и само содержимое. Сервер потом это всё аккуратно разбирает.
Вот тебе живой пример на Dart/Flutter с пакетом http. Смотри, как это просто:
import 'package:http/http.dart' as http;
Future<void> uploadImage(String imagePath, String description) async {
// Создаём запрос, как будто форму на сайте заполняем
var request = http.MultipartRequest(
'POST',
Uri.parse('https://api.example.com/upload'),
);
// Цепляем файлик. 'image' — это имя поля, куда его суём.
request.files.add(
await http.MultipartFile.fromPath(
'image',
imagePath,
contentType: MediaType('image', 'jpeg'),
),
);
// А тут обычное текстовое поле, типа комментария
request.fields['description'] = description;
try {
// Поехали, отправляем!
final response = await request.send();
if (response.statusCode == 200) {
print('Файл успешно загружен');
} else {
print('Ошибка: ${response.statusCode}');
}
} catch (e) {
// Ну тут всё понятно, сеть — она такая, хитрая жопа
print('Ошибка сети: $e');
}
}
Когда эту банду multipart/form-data вызывать на дело:
- Загрузка файлов на сервер — фотки, документы, что угодно. Без этого — никуда.
- Отправка сложных форм, где вперемешку и текст, и файлы. Как та самая HTML-форма с
enctype="multipart/form-data". - Когда пишешь API, которое должно понимать такие же запросы, как браузер. В общем, стандартная история, но доверия к ней, блядь, ноль, если не проверишь границу (boundary) дважды.