如何在FastAPI中重路由请求至其他URL/端点并修改请求头?
FastAPI中间件实现内部重路由与请求头修改
你当前的代码实现的是客户端重定向(返回3xx状态码让客户端跳转新URL),但如果需要服务器内部的重路由(客户端无感知,直接转发请求到目标路由)以及修改请求头,FastAPI是完全支持的,核心是操作Request对象的scope字典(因为request.url是基于scope生成的只读属性,而scope本身可修改)。
实现方案代码示例
from fastapi import Request, FastAPI app = FastAPI() def matches_certain_format(path: str) -> bool: # 自定义路径匹配逻辑,示例:匹配以"/legacy/"开头的路径 return path.startswith("/legacy/") def create_target_url(path: str) -> str: # 自定义路径转换逻辑,示例:将"/legacy/"替换为"/v2/" return path.replace("/legacy/", "/v2/", 1) @app.middleware("http") async def internal_rewrite_middleware(request: Request, call_next): # 1. 实现内部重路由 if matches_certain_format(request.url.path): new_path = create_target_url(request.url.path) # 修改scope中的path,后续路由会匹配新路径 request.scope["path"] = new_path # 若需修改域名、协议等,可同步修改scope的对应字段 # request.scope["scheme"] = "https" # request.scope["server"] = ("api.example.com", 443) # 2. 修改请求头 # 方式1:替换现有请求头 updated_headers = [] for name, value in request.scope["headers"]: if name == b"x-original-header": updated_headers.append((b"x-modified-header", b"new-value")) else: updated_headers.append((name, value)) # 方式2:添加新请求头 updated_headers.append((b"x-added-header", b"added-value")) request.scope["headers"] = updated_headers # 继续处理修改后的请求 response = await call_next(request) return response
关键说明
- 内部重路由原理:
request.url是基于request.scope字典生成的只读属性,但scope本身是可修改的字典。修改scope["path"]后,FastAPI后续的路由匹配会使用新路径,整个过程在服务器内部完成,客户端不会收到重定向响应,也感知不到路径变化。 - 请求头修改注意事项:
scope["headers"]存储的是字节类型的键值对列表(格式为[(b"header-key", b"value"), ...]),修改时必须保证键和值都是bytes类型,否则会引发错误。 - 与重定向的区别:你之前的
RedirectResponse是客户端跳转,会返回3xx状态码,客户端需要重新发起请求;而内部重路由是服务器端直接转发,返回的是目标路由的正常响应码(如200),体验更流畅。
内容的提问来源于stack exchange,提问作者Aniket Tiratkar
相关产品推荐
相关产品推荐

