代理代码
- 使用httpx库
- 异步代理
async def reverse_proxy_request(url, method, post_data):
async with httpx.AsyncClient() as client:
# 发起代理请求
try:
if method == "GET":
response = await client.get(url)
elif method == "POST":
response = await client.post(url, json=post_data)
else:
response = await client.get(url)
except httpx.RequestError:
raise HTTPException(status_code=500, detail="Failed to proxy the request")
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="Failed to proxy the request")
content_type = response.headers.get("Content-Type", "").lower()
return response.text, content_type
完整接口
注意⚠️:这里的代理,只是在数据库做一个地址映射,不是真正的代理(fastapi目前没有支持的库和组件)。所以这个地址可能还会调用其他的地址来获取一些信息,js文件等,需要将接口配置为复用以及通配。
:::info
比如 GET http://dev.a.com/dash1 <–> 代理 <–> http://dev.b.com/dash1
这时http://dev.b.com/dash1需要请求一些其他的js文件、或者post请求其他地址获取数据,但是再次请求是由http://dev.a.com/dash1发起的,也就是会变为 POST http://dev.a.com/dash1或者GET http://dev.a.com/dash1/need.js。也就是接口需要做循环代理的
:::
@router.api_route(path="/godash/{report_name}/{file_path:path}", methods=["GET", "POST"])
async def mapping_url(request: Request, report_name: str, file_path: Optional[str] = None,
db: AsyncSession = Depends(get_session)):
try:
method = request.method
if method == "POST":
post_data = await request.json()
mapping = redis_client.get(report_name)
url = mapping.decode()
if file_path:
url = urljoin(url, file_path)
response, content_type = await reverse_proxy_request(url, method, post_data)
return HTMLResponse(content=response, status_code=200, headers={"content-type": content_type})
except Exception as e:
traceback.print_exc()
logger.info(f"error,{e}")
raise HTTPException(status_code=404, detail=f"reportMapping error,{e}")
async def reverse_proxy_request(url, method, post_data):
async with httpx.AsyncClient() as client:
# 发起代理请求
try:
if method == "GET":
response = await client.get(url)
elif method == "POST":
response = await client.post(url, json=post_data)
else:
response = await client.get(url)
except httpx.RequestError:
raise HTTPException(status_code=500, detail="Failed to proxy the request")
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="Failed to proxy the request")
content_type = response.headers.get("Content-Type", "").lower()
return response.text, content_type