← Назад к вопросам
Из чего состоит структура HTTP-запроса
1.3 Junior🔥 251 комментариев
#REST API и HTTP
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Структура HTTP-запроса
HTTP-запрос — это сообщение, которое клиент (браузер, мобильное приложение) отправляет серверу для получения ресурса или выполнения действия. Структура запроса стандартизирована и состоит из четырех основных частей.
Основные части HTTP-запроса
1. Request Line (Строка запроса)
METHOD /path/to/resource?param1=value1¶m2=value2 HTTP/1.1
Компоненты:
- METHOD — HTTP метод (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
- URI — путь и параметры ресурса
- HTTP Version — версия протокола (HTTP/1.1, HTTP/2, HTTP/3)
Примеры:
GET /api/users HTTP/1.1
POST /api/users HTTP/1.1
DELETE /api/users/123 HTTP/1.1
PUT /api/users/123 HTTP/1.1
2. Request Headers (Заголовки)
Описывают метаинформацию о запросе:
Host: example.com
User-Agent: Mozilla/5.0 (Chrome/91.0)
Accept: application/json
Content-Type: application/json
Content-Length: 1234
Authorization: Bearer token_123456
Cookie: session_id=abc123; user_pref=dark_mode
Частые заголовки:
| Заголовок | Описание |
|---|---|
| Host | Хост сервера, к которому идет запрос |
| User-Agent | Информация о клиенте (браузер, ОС) |
| Accept | Формат, который клиент может принять (JSON, HTML) |
| Content-Type | Формат отправляемых данных |
| Content-Length | Размер тела запроса в байтах |
| Authorization | Токен аутентификации |
| Cookie | Cookies сессии и предпочтений |
| Referer | Откуда клиент пришел |
| Accept-Encoding | Сжатие (gzip, deflate) |
| X-Custom-Header | Кастомные заголовки (с префиксом X-) |
3. Empty Line (Пустая строка)
\r\n\r\n
Отделяет заголовки от тела запроса.
4. Request Body (Тело запроса)
Содержит данные, отправляемые серверу:
{
"username": "alice",
"password": "secret123",
"email": "alice@example.com"
}
Body обязателен для:
- POST запросов
- PUT запросов
- PATCH запросов
Body НЕ отправляется для:
- GET запросов
- DELETE запросов (обычно)
- HEAD запросов
Полный пример HTTP-запроса
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 52
Authorization: Bearer eyJhbGc...
Accept: application/json
{
"name": "Alice",
"email": "alice@example.com",
"age": 30
}
HTTP Методы
GET — получить ресурс
GET /api/users/123 HTTP/1.1
Host: api.example.com
# Нет body
# Безопасный (не меняет данные)
# Можно кешировать
POST — создать ресурс
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{"name": "Alice", "email": "alice@example.com"}
# Есть body
# Может иметь side effects
PUT — полностью заменить ресурс
PUT /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{"name": "Alice Updated", "email": "alice_new@example.com"}
# Замена всех полей
PATCH — частично обновить ресурс
PATCH /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{"email": "alice_new@example.com"}
# Обновление только переданных полей
DELETE — удалить ресурс
DELETE /api/users/123 HTTP/1.1
Host: api.example.com
# Нет body
HEAD — как GET, но без body
HEAD /api/users HTTP/1.1
Host: api.example.com
# Используется для проверки доступности ресурса
# Возвращает только заголовки, не body
Примеры с Python
С использованием requests
import requests
# GET запрос
response = requests.get(
'https://api.example.com/api/users/123',
headers={
'Authorization': 'Bearer token_123',
'Accept': 'application/json'
}
)
# POST запрос с данными
response = requests.post(
'https://api.example.com/api/users',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer token_123'
},
json={
'name': 'Alice',
'email': 'alice@example.com'
}
)
# PATCH запрос
response = requests.patch(
'https://api.example.com/api/users/123',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer token_123'
},
json={'email': 'alice_new@example.com'}
)
# DELETE запрос
response = requests.delete(
'https://api.example.com/api/users/123',
headers={'Authorization': 'Bearer token_123'}
)
С использованием curl
# GET
curl https://api.example.com/api/users/123 \
-H 'Authorization: Bearer token_123'
# POST
curl -X POST https://api.example.com/api/users \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer token_123' \
-d '{"name": "Alice", "email": "alice@example.com"}'
# PATCH
curl -X PATCH https://api.example.com/api/users/123 \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer token_123' \
-d '{"email": "alice_new@example.com"}'
# DELETE
curl -X DELETE https://api.example.com/api/users/123 \
-H 'Authorization: Bearer token_123'
Как выглядит сырой HTTP-запрос
# Если бы мы отправляли вручную через socket
import socket
request = b'''POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 52
{"name": "Alice", "email": "alice@example.com"}'''
socket_obj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_obj.connect(('api.example.com', 80))
socket_obj.sendall(request)
response = socket_obj.recv(4096)
Типичные проблемы при работе с запросами
1. Неправильный Content-Type
# ❌ Плохо: отправляем JSON, но говорим что это form
response = requests.post(
'https://api.example.com/api/users',
headers={'Content-Type': 'application/x-www-form-urlencoded'},
json={'name': 'Alice'} # Сервер не поймет
)
# ✅ Хорошо
response = requests.post(
'https://api.example.com/api/users',
headers={'Content-Type': 'application/json'},
json={'name': 'Alice'}
)
2. Отсутствие Authorization
# ❌ Плохо: забыли авторизацию
response = requests.get('https://api.example.com/api/users')
# 401 Unauthorized
# ✅ Хорошо
response = requests.get(
'https://api.example.com/api/users',
headers={'Authorization': 'Bearer token_123'}
)
3. Query параметры vs Body
# GET с параметрами в URL
response = requests.get(
'https://api.example.com/api/users',
params={'status': 'active', 'page': 1}
)
# URL: /api/users?status=active&page=1
# POST с данными в body
response = requests.post(
'https://api.example.com/api/users',
json={'name': 'Alice'} # В body
)
4. Content-Length
# Обычно requests считает Content-Length автоматически
response = requests.post(
'https://api.example.com/api/users',
json={'name': 'Alice'}
)
# requests добавит Content-Length автоматически
# Но если отправляем вручную:
data = b'{"name": "Alice"}'
headers = {'Content-Length': len(data)} # Важно!
FastAPI и HTTP-запросы
from fastapi import FastAPI, Header, Body
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
email: str
@app.get('/api/users/{user_id}')
def get_user(
user_id: int,
authorization: str = Header(...) # Из заголовков
):
return {'id': user_id}
@app.post('/api/users')
def create_user(
user: User, # Из body (JSON)
authorization: str = Header(...) # Из заголовков
):
return {'id': 1, 'name': user.name, 'email': user.email}
@app.patch('/api/users/{user_id}')
def update_user(
user_id: int,
user: User # Из body
):
return {'id': user_id}
@app.delete('/api/users/{user_id}')
def delete_user(user_id: int):
return {'status': 'deleted'}
Итоговое резюме
HTTP-запрос состоит из:
- Request Line — метод, путь, версия
- Headers — метаинформация
- Empty Line — разделитель
- Body — данные (опционально)
Помни:
- GET обычно без body
- POST/PUT/PATCH — с body
- Всегда указывай правильный Content-Type
- Authorization идет в заголовках
- Content-Length обычно вычисляется автоматически