You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular调用FastAPI POST接口遇422错误:请求参数无法被后端识别

Angular调用FastAPI POST接口返回422错误的解决方法

在使用Angular的HttpClient.post调用FastAPI的POST登录接口时,后端无法接收请求参数,返回422 (Unprocessable Entity)错误,但Postman调用该接口完全正常。

后端FastAPI代码

from typing import Optional
from pydantic import BaseModel
class UsersLoginRequest(BaseModel):
    username: str
    password: str

@users_router.post("/login")
def login(body: UsersLoginRequest):
    pass

Postman正常调用示例(cURL)

curl --location --request POST 'http://127.0.0.1:3101/users/login' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "username": "admin",
    "password": "admin"
}'

Postman调用后后端返回200 OK,说明接口本身逻辑正常。

错误的Angular写法及对应问题

写法一:将HttpParams作为请求体传递

import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';

constructor(private http: HttpClient) {}

signIn(): void { 
    const headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');

    let params = new HttpParams()
    .append('username', "admin")
    .append('password', "admin")

    this.http.post('http://127.0.0.1:3101/users/login', params, { headers: headers })
    .subscribe({ 
        error: (response: any) => {},
        next: (response: any) => {}
    })
}

后端日志:

INFO:     127.0.0.1:62969 - "POST /users/login HTTP/1.1" 422 Unprocessable Entity

写法二:将参数放在params选项中

import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';

constructor(private http: HttpClient) {}

signIn(): void {
    const headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');

    let params = new HttpParams()
    .append('username', "admin")
    .append('password', "admin")

    this.http.post('http://127.0.0.1:3101/users/login', null, { headers: headers, params: params })
    .subscribe({ 
        error: (response: any) => {},
        next: (response: any) => {}
    })
}

后端日志同样返回422 Unprocessable Entity。

问题根源及正确写法

问题根源

  1. HttpHeaders的不可变性:headers.append()不会修改原对象,而是返回新的Headers对象,原headers变量仍为空,导致请求没有正确携带Content-Type: application/json头。
  2. 参数传递方式错误:FastAPI的接口通过BaseModel接收JSON请求体,但两种错误写法都没有传递正确的JSON请求体:
    • 写法一把HttpParams(本质是URL查询参数格式)作为请求体发送,不符合JSON格式
    • 写法二把参数放在params选项中,这会将参数拼接在URL后面作为查询参数,而FastAPI接口是从请求体读取数据

正确的Angular写法

import { HttpClient, HttpHeaders } from '@angular/common/http';

constructor(private http: HttpClient) {}

signIn(): void { 
    // 正确设置HttpHeaders:append后重新赋值
    const headers = new HttpHeaders().append('Content-Type', 'application/json');

    // 直接构造JSON格式的请求体
    const body = {
        username: "admin",
        password: "admin"
    };

    this.http.post('http://127.0.0.1:3101/users/login', body, { headers: headers })
    .subscribe({ 
        error: (response: any) => {},
        next: (response: any) => {}
    })
}

简化写法(Angular默认会为JSON请求体添加Content-Type)

Angular的HttpClient.post在传递普通JavaScript对象作为请求体时,会自动设置Content-Type: application/json头,所以可以省略手动设置headers:

import { HttpClient } from '@angular/common/http';

constructor(private http: HttpClient) {}

signIn(): void { 
    const body = {
        username: "admin",
        password: "admin"
    };

    this.http.post('http://127.0.0.1:3101/users/login', body)
    .subscribe({ 
        error: (response: any) => {},
        next: (response: any) => {}
    })
}

内容的提问来源于stack exchange,提问作者Abdulwahabdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:45:47