1. HTTP-запросы с телом: POST и PUT
HTTP-запрос — это не просто "дай мне что-нибудь". Это полноценное письмо серверу, где можно указать метод (GET, POST, PUT, DELETE), добавить тело (body) с данными (например, ваш новый пост или форму регистрации), а ещё — приложить кучу конвертов с дополнительной информацией (заголовки: Content-Type, Authorization и др.).
Примеры из жизни:
- Отправка формы регистрации пользователя (POST с JSON в теле).
- Обновление данных профиля (PUT с телом).
- Аутентификация (заголовок Authorization).
- Загрузка файла (POST с multipart/form-data).
- Фильтрация/поиск (GET с query-параметрами или POST с фильтром в теле).
В Angular всё это делается через сервис HttpClient. Давайте разберёмся, как!
POST: отправка данных на сервер
Когда вы хотите что-то создать (например, нового пользователя), используйте метод post. Он принимает минимум два аргумента: URL и тело запроса.
import { HttpClient } from '@angular/common/http';
constructor(private http: HttpClient) {}
addUser(user: { name: string; email: string }) {
return this.http.post('/api/users', user);
}
В этом примере мы отправляем объект user на сервер. Angular автоматически преобразует объект в JSON и устанавливает заголовок Content-Type: application/json.
Пример с подпиской:
this.addUser({ name: 'Вася', email: 'vasya@example.com' })
.subscribe({
next: response => console.log('Пользователь создан!', response),
error: err => console.error('Ошибка:', err)
});
PUT: обновление данных
PUT похож на POST, но обычно используется для обновления существующего ресурса.
updateUser(id: number, user: { name: string; email: string }) {
return this.http.put(`/api/users/${id}`, user);
}
DELETE: иногда тоже с телом (редко)
Стандарт HTTP не запрещает отправлять тело в DELETE-запросе, но большинство серверов этого не ждёт. Обычно DELETE — без тела, но если вдруг нужно, Angular позволяет передать его третьим параметром (options).
2. Передача заголовков (headers)
Иногда сервер требует дополнительные заголовки: например, токен авторизации, тип содержимого, настройки кеширования и т.д.
В Angular для этого используется класс HttpHeaders. Заголовки передаются через третий параметр метода запроса:
import { HttpHeaders } from '@angular/common/http';
const headers = new HttpHeaders({
'Authorization': 'Bearer my-super-secret-token',
'X-Custom-Header': 'SomeValue'
});
this.http.post('/api/secure', { data: 123 }, { headers })
.subscribe(...);
Особенности работы с HttpHeaders
- HttpHeaders — иммутабельный (неизменяемый) объект. Методы set, append возвращают новый объект, а не меняют существующий.
- Можно создавать "цепочки":
const headers = new HttpHeaders()
.set('Authorization', 'Bearer supertoken')
.set('X-Request-ID', 'abc123');
- Если вы хотите добавить заголовок к уже существующим:
let headers = new HttpHeaders();
headers = headers.set('Authorization', 'Bearer token');
headers = headers.set('Another', 'value');
3. Полезные нюансы
Передача query-параметров
Иногда сервер ждёт параметры не в теле, а в строке запроса (например, фильтр, пагинация):
import { HttpParams } from '@angular/common/http';
const params = new HttpParams()
.set('page', '2')
.set('pageSize', '10');
this.http.get('/api/users', { params })
.subscribe(...);
Полная сигнатура HTTP-запроса
Для всех методов (get, post, put, delete, ...) третий параметр — это объект с дополнительными настройками:
this.http.post(
'/api/users',
{ name: 'Петя' },
{
headers: new HttpHeaders({ 'Authorization': 'Bearer token' }),
params: new HttpParams().set('role', 'admin'),
observe: 'body', // или 'response', если нужны заголовки ответа
responseType: 'json' // или 'text', 'blob'
}
)
.subscribe(...);
Отправка произвольных типов данных
JSON (по умолчанию)
Angular автоматически сериализует объект в JSON, если вы отправляете обычный объект.
FormData (отправка файлов)
Если нужно отправить файл, используйте FormData:
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('description', 'Мой файл');
this.http.post('/api/upload', formData)
.subscribe(...);
Внимание: Angular сам выставит нужный заголовок Content-Type: multipart/form-data — не нужно делать это вручную!
Текст или Blob
Если сервер ждёт обычный текст или бинарные данные:
this.http.post('/api/text', 'Привет, сервер!', {
headers: new HttpHeaders({ 'Content-Type': 'text/plain' }),
responseType: 'text'
})
.subscribe(...);
4. Пример: Асинхронная отправка формы регистрации с заголовками
Давайте добавим в наше учебное приложение функцию регистрации пользователя, с отправкой тела и заголовка авторизации.
user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}
register(user: { name: string; email: string; password: string }) {
const headers = new HttpHeaders({
'Authorization': 'Bearer test-token'
});
return this.http.post('/api/register', user, { headers });
}
}
user.component.ts
import { Component } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-user-register',
template: `
<form (ngSubmit)="onSubmit()">
<input [(ngModel)]="user.name" name="name" placeholder="Имя">
<input [(ngModel)]="user.email" name="email" placeholder="Email">
<input [(ngModel)]="user.password" name="password" type="password" placeholder="Пароль">
<button type="submit">Зарегистрироваться</button>
</form>
`
})
export class UserRegisterComponent {
user = { name: '', email: '', password: '' };
constructor(private userService: UserService) {}
onSubmit() {
this.userService.register(this.user)
.subscribe({
next: res => alert('Регистрация успешна!'),
error: err => alert('Ошибка регистрации: ' + err.message)
});
}
}
5. Типичные ошибки при отправке HTTP-запросов с телом и заголовками
Ошибка №1: Попытка вручную выставить Content-Type для FormData
Если вы отправляете FormData (например, с файлом), не выставляйте Content-Type вручную! Браузер сам подставит нужный boundary, иначе сервер не сможет разобрать файл.
Ошибка №2: Мутирование HttpHeaders
Не забывайте, что HttpHeaders — иммутабельный. Каждый вызов set возвращает новый объект. Если вы делаете так:
const headers = new HttpHeaders();
headers.set('Authorization', 'Bearer token'); // ничего не произойдёт!
Заголовок не добавится! Нужно писать:
const headers = new HttpHeaders().set('Authorization', 'Bearer token');
Ошибка №3: Передача сложных объектов как query-параметров
Если вы пытаетесь передать массив или объект через HttpParams, Angular не сериализует их как JSON. Нужно сериализовать вручную или использовать несколько .set() для каждого значения.
Ошибка №4: Необработанные ошибки сервера
Если сервер возвращает ошибку (например, 400 или 500), а вы не подписались на error в subscribe/catchError, пользователь не узнает о проблеме.
Ошибка №5: Несовпадение Content-Type и типа тела
Если вы указали Content-Type: application/json, а отправляете строку или FormData — сервер может не понять ваш запрос. Следите за соответствием типа тела и заголовка.
Ошибка №6: Передача токена в теле вместо заголовка
Токены авторизации (например, JWT) всегда передаются в заголовке Authorization, а не в теле запроса. Не путайте!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ