Возможно ли отправить файл в теле HTTP GET-запроса

«Возможно ли отправить файл в теле HTTP GET-запроса» — вопрос из категории Сети, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, согласно спецификации HTTP (RFC 7231) и общепринятым практикам, GET-запросы не должны иметь тела (body) и не предназначены для отправки данных на сервер.

Почему это не работает и является плохой практикой

  • Семантика HTTP: Метод GET предназначен исключительно для получения (извлечения) данных с сервера. Для отправки данных или файлов следует использовать POST или PUT.
  • Игнорирование тела запроса: Большинство веб-серверов, прокси и кеширующих серверов сконфигурированы так, чтобы полностью игнорировать или отбрасывать тело GET-запроса. Ваша отправка просто не дойдет до серверного приложения.
  • Идемпотентность: GET-запросы должны быть идемпотентными, то есть многократное повторение одного и того же запроса должно приводить к тому же результату и не изменять состояние сервера. Отправка файла — это операция, изменяющая состояние.

Правильный способ: POST с multipart/form-data

Для загрузки файлов на сервер используется метод POST с типом контента multipart/form-data.

Пример на Python с использованием библиотеки requests:

import requests

# URL эндпоинта для загрузки
url = 'https://api.example.com/upload'

# Файл, который нужно отправить
file_path = 'document.pdf'

try:
    with open(file_path, 'rb') as f:
        # 'rb' - чтение в бинарном режиме
        files = {'file': (file_path, f, 'application/pdf')}

        response = requests.post(url, files=files)

        response.raise_for_status() # Проверка на HTTP-ошибки
        print(f"Файл успешно загружен! Ответ сервера: {response.json()}")

except FileNotFoundError:
    print(f"Ошибка: файл не найден по пути {file_path}")
except requests.exceptions.RequestException as e:
    print(f"Ошибка при отправке запроса: {e}")

Попытка передать файл через GET (например, закодировав его в Base64 и вставив в URL) является грубым антипаттерном из-за резкого увеличения размера URL и ограничений на его длину.