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

GET请求URI保留字符经encodeURIComponent编码后FastAPI报404问题咨询

出现该问题的核心原因是Uvicorn等ASGI服务器会先对URL路径做一次解码,将%2F转为/后再交给FastAPI做路由匹配,导致原本的单段路径被拆分为多段,无法匹配预设路由。可通过以下方式解决:

方案1(最推荐):改用查询参数传递特殊标识

将原本放在路径中需要保留%2F等编码字符的参数挪到查询参数中传递,例如修改请求格式为:

http://localhost:4200/api/verifiers?target=https%3A%2F%2Fwww.web.com%2Fdev%2F0&service=xx%3Ayy%3AV00000000000000000000000000000000000000000000000000000000000000000000000000000000%23read-device

FastAPI接收查询参数时不会提前对内容做路径拆分,可完整读取编码后的内容,符合HTTP设计规范,无兼容风险。

方案2:使用path路径转换器捕获全段内容

如果必须将参数放在路径中,可在路由定义时使用FastAPI提供的path类型转换器,将可变路径段全部捕获后自行拆分解析:

from fastapi import FastAPI

app = FastAPI()

@app.get("/verifiers/{full_path:path}")
async def handle_verifier(full_path: str):
    # 手动拆分full_path,提取目标url和service标识
    target_url, service_id = full_path.rsplit("/services/", 1)
    # 后续业务逻辑

该方案会匹配/verifiers/之后的所有路径内容,不会因为编码后的%2F被解码为/导致路由匹配失败。

方案3:前端对路径参数做二次编码

前端在拼接路径前,对需要放入路径的参数执行两次encodeURIComponent处理:

// 前端Angular代码示例
const target = "https://www.web.com/dev/0";
const encodedTarget = encodeURIComponent(encodeURIComponent(target));
const serviceId = "xx:yy:V00000000000000000000000000000000000000000000000000000000000000000000000000000000#read-device";
const encodedService = encodeURIComponent(encodeURIComponent(serviceId));
// 拼接后路径中的%2F会被转为%252F,服务器解码一次后保留为%2F不会拆分路径
const requestUrl = `/api/verifiers/${encodedTarget}/services/${encodedService}`;

后端拿到参数后,执行一次urllib.parse.unquote即可得到原始内容。

该方案需要前后端配合修改,适合不想调整路由结构的场景,但不如方案1通用稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:06:04