FastAPI GET接口响应无法完整传输至Angular前端,存在内容长度不匹配/分块编码不完整问题
FastAPI GET接口响应无法完整传输至Angular前端,存在内容长度不匹配/分块编码不完整问题
我刚接触FastAPI和Angular,现在遇到一个特别头疼的问题——用Angular调用后端GET接口时,响应永远传不全。但用Postman或者curl请求的话,响应是完整的,唯独Angular这边总是卡住。
我试过切换fetch和HttpClient两种请求方式,也试过分块传输和常规传输,但都不管用。最接近成功的一次是用fetch加分块传输,但核心问题好像还是出在内容长度不匹配上,Angular里会报net::ERR_CONTENT_LENGTH_MISMATCH,实际传输的数据量和预期的完全对不上:
15.7 kB / 434 kB transferred 15.4 kB / 7.8 MB resources Finish: 3.4 min
后来我给FastAPI加了timeout_keep_alive参数,结果只是让它卡得更久才报错,这次的错误变成了(failed)net::ERR_INCOMPLETE_CHUNKED_ENCODING。对应的API启动代码是:
def run_api(): uvicorn.run( app, host="-----", port=---, timeout_keep_alive=200)
我之前有几个POST接口是能正常工作的,但这个GET接口完全不行。有个情况可能特殊一点:后端API部署在EC2实例上,我本地用HTTP调用,但同样的环境下POST接口是没问题的。
我的CORS中间件配置如下:
app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
Angular这边的请求代码:
public getAttachmentMetadata(): Observable<any> { return new Observable(observer => { const token = this.cookieService.get('session_token'); console.log("Retrieved token:", token); const url = token ? `${this.API_URL}?token=${encodeURIComponent(token)}` : this.API_URL; fetch(url, { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json' } }) .then(response => { console.log("Response Status:", response.status); console.log("Response Headers:", response.headers); return response; }) .catch(error => { console.error("Error fetching metadata:", error); observer.error(error); }); }); }
FastAPI的路由和分块响应实现:
attachments_router = APIRouter(prefix="/attachments", tags=["attachments"]) @attachments_router.get("/get/metadata") async def get_attachments(): data = get_attachments_tables() # return data #THIS IS THE WAY WITHOUT SENDING IN CHUNKS return StreamingResponse(stream_json_response(data), media_type="application/json") async def stream_json_response(data): """ Streams a JSON response while ensuring full nested data transfer. """ yield '{"success": true, "message": "Success", "data": {' first_key = True for key, value in data.items(): if not first_key: yield "," else: first_key = False yield json.dumps(key) + ": " + json.dumps(value, default=str) await asyncio.sleep(0) yield "}}" await asyncio.sleep(1)
现在我完全搞不懂问题出在哪了,任何建议都欢迎,如果需要更多信息也可以告诉我,谢谢!
备注:内容来源于stack exchange,提问作者Broderick Boucher
相关产品推荐
相关产品推荐

