Может ли GET-запрос выполнять роль POST-запроса?

«Может ли GET-запрос выполнять роль POST-запроса?» — вопрос из категории HTTP и веб-протоколы, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Технически — может, но это нарушает семантику HTTP и является плохой практикой, которую QA должен выявлять.

GET предназначен для идемпотентного получения данных без побочных эффектов. Все параметры передаются в URL, что ограничивает длину и подвергает данные риску (они попадают в логи сервера, историю браузера).

POST предназначен для отправки данных, которые могут изменять состояние на сервере (создание заказа, отправка формы). Данные передаются в теле запроса.

Пример риска, который я проверяю при тестировании безопасности (OWASP): Если приложение использует GET для критических действий (например, GET /api/transfer?amount=1000&to=account123), это делает его уязвимым к CSRF-атакам и утечке данных через Referer-заголовок.

Как я тестирую это:

  1. Анализ спецификации API: Сверяюсь с OpenAPI/Swagger-документацией.
  2. Ручное тестирование: Пытаюсь отправить данные с телом (JSON) через GET-запрос в Postman — сервер должен возвращать ошибку 405 Method Not Allowed или 400 Bad Request.
  3. Автотесты: Пишу тест, который проверяет, что эндпоинты для модификации данных не реагируют на GET.
# Пример негативного теста с помощью pytest
def test_get_request_should_not_accept_body(api_client):
    """Попытка отправить тело JSON в GET-запросе должна завершиться ошибкой."""
    payload = {"action": "delete"}
    # Важно: библиотека requests неявно запрещает body в GET, но некоторые клиенты могут его отправить.
    response = api_client.session.get(api_client.endpoints['/user'], json=payload)
    # Ожидаем, что сервер отвергнет такой запрос
    assert response.status_code in [400, 405, 411]

Корректный API должен строго разделять методы по их семантическому назначению.