Ответ
Да, файлы передаются в теле HTTP-запроса. Основные методы — использование типа контента multipart/form-data для форм или application/octet-stream для бинарных данных.
1. Multipart/form-data (Стандарт для HTML-форм и API)
Используется, когда нужно отправить файлы вместе с другими полями формы.
Пример HTTP-запроса:
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=MyBoundary123
--MyBoundary123
Content-Disposition: form-data; name="description"
Профильное фото
--MyBoundary123
Content-Disposition: form-data; name="file"; filename="avatar.jpg"
Content-Type: image/jpeg
<бинарные данные файла>
--MyBoundary123--
Пример на JavaScript с fetch:
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('comment', 'Мой файл');
fetch('/api/upload', {
method: 'POST',
body: formData // Заголовок Content-Type установится автоматически
});
2. Direct Binary Upload
Файл передается как есть, без дополнительных полей.
Пример:
PUT /files/avatar.jpg HTTP/1.1
Host: example.com
Content-Type: application/octet-stream
<бинарные данные файла>
Ключевые моменты:
- Для больших файлов используйте
Content-LengthилиTransfer-Encoding: chunked. - Всегда проверяйте MIME-тип и размер файла на сервере в целях безопасности.
Ответ 18+ 🔞
А, ну, про передачу файлов по HTTP, да? Ну, это ж классика, блядь, каждый день этим пользуемся, а потом удивляемся, почему сервер лёг, ёпта.
Короче, есть два основных способа, как эту бинарную хуйню в сеть запихнуть.
1. Multipart/form-data (Это когда с формами возимся)
Этот способ — как раз для тех случаев, когда тебе надо не только файлик пришлёпнуть, но ещё и какую-нибудь подпись к нему прилепить, типа «смотрите, какая у меня фотка с отпуска, блядь».
Вот смотри, как запрос выглядит изнутри, страшненько:
POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=MyBoundary123
--MyBoundary123
Content-Disposition: form-data; name="description"
Профильное фото
--MyBoundary123
Content-Disposition: form-data; name="file"; filename="avatar.jpg"
Content-Type: image/jpeg
<тут прям бинарные данные, ну, нули и единички, короче>
--MyBoundary123--
Видишь эту boundary? Это типа разделитель, чтобы сервер не запутался, где у тебя описание кончается, а где файл начинается. Без него — пиздец, всё в кучу смешается.
А на фронтенде это вообще в две строки делается, ебать мои старые костыли:
const formData = new FormData();
formData.append('file', fileInput.files[0]); // Вот твой файл
formData.append('comment', 'Мой файл'); // А вот твоя подпись, типа "шедевр"
fetch('/api/upload', {
method: 'POST',
body: formData // И даже голову ломать не надо — браузер сам всё красиво завернёт!
});
2. Прямая загрузка бинарника (Direct Binary Upload)
А это уже для минималистов, блядь. Никаких лишних телодвижений. Берёшь файл — и пиздуй его как есть, голеньким. Часто через PUT метод.
Пример запроса:
PUT /files/avatar.jpg HTTP/1.1
Host: example.com
Content-Type: application/octet-stream
<и опять эти нули и единички, весь файл целиком>
А теперь, блядь, самое важное, чтобы потом не охуеть от последствий:
- Размер файла: Если файл здоровый, как чёрт, обязательно указывай
Content-Length, а то сервер будет ждать, пока ты всё сольёшь, или используйTransfer-Encoding: chunked— это когда файл кусочками отправляешь. - Безопасность, ёпта! На сервере ты ОБЯЗАН проверять две вещи, а то тебе пидары налетят:
- MIME-тип. Не верь тому, что в заголовке написали. Файл может называться
kartinka.jpg, а внутри — скрипт на PHP, который сервер тебе ебалом вынесет. Проверяй сигнатуры, магические числа — вот это всё. - Размер. Ограничивай, блядь, сразу. А то какой-нибудь умник попробует тебе терабайтный дамп базы залить, и твой сервер накроется медным тазом, в рот меня чих-пых.
- MIME-тип. Не верь тому, что в заголовке написали. Файл может называться
Вот и вся наука. Главное — не выёбывайся и делай по уму, чтобы потом не пришлось объяснять, почему у тебя на сервере порно с котиками вместо логотипа компании лежит.