FastAPI如何解码非UTF-8请求体(ISO-8859-1编码)
FastAPI接收ISO-8859-1编码请求并绑定Pydantic模型的解决方法
FastAPI默认处理text/plain请求体时,不管Content-Type头里的charset参数,都会强制用UTF-8解码——这是因为底层Starlette框架的PlainTextRequestParser硬编码了UTF-8作为默认编码,不会从请求头里提取charset信息。下面给两个可行的解决方案:
方案一:自定义全局请求解析器(推荐)
直接替换Starlette默认的text/plain解析器,让它能从Content-Type头里读取charset并正确解码:
from fastapi import FastAPI from starlette.requests import PlainTextRequestParser import cgi from pydantic import BaseModel # 自定义解析器,支持从Content-Type提取charset class CharsetAwarePlainTextParser(PlainTextRequestParser): async def parse(self): content_type = self.request.headers.get("content-type", "") _, options = cgi.parse_header(content_type) encoding = options.get("charset", "utf-8") body = await self.request.body() text = body.decode(encoding) # 按Starlette要求返回FormData格式,让FastAPI能绑定到Pydantic模型 return self.form_data_class({"text": text}) app = FastAPI() # 替换默认的text/plain解析器 app.router.request_parseors["text/plain"] = CharsetAwarePlainTextParser # 定义Pydantic模型 class RequestModel(BaseModel): text: str # 端点直接接收模型 @app.post("/process") async def process_request(model: RequestModel): return {"decoded_content": model.text}
这个方案全局生效,所有接收text/plain的端点都会自动适配请求头里指定的编码,不用每个端点重复处理。
方案二:用依赖项处理单个端点
如果只是少数端点需要支持ISO-8859-1,不想修改全局配置,可以用依赖项单独处理解码:
from fastapi import FastAPI, Depends, Request from pydantic import BaseModel import cgi app = FastAPI() class RequestModel(BaseModel): text: str # 定义依赖项,负责解码请求体 async def decode_request_body(request: Request) -> str: content_type = request.headers.get("content-type", "") _, options = cgi.parse_header(content_type) encoding = options.get("charset", "utf-8") body = await request.body() return body.decode(encoding) # 端点通过依赖项获取解码后的文本,再绑定到模型 @app.post("/process") async def process_request(decoded_text: str = Depends(decode_request_body)): model = RequestModel(text=decoded_text) return {"decoded_content": model.text}
这个方案更灵活,只对添加了该依赖项的端点生效,适合局部特殊场景。
补充说明
- 两个方案都遵循HTTP规范:如果请求头没指定charset,会自动 fallback 到UTF-8解码。
- 自定义解析器方案更适合全局需要支持多种编码的服务,依赖项方案适合单点特殊处理。
内容的提问来源于stack exchange,提问作者oliviaoil
相关产品推荐
相关产品推荐

