FastAPI删除接口返回204时执行后台任务报内容长度错误
问题分析与解决
升级Starlette到0.27.0或FastAPI到0.96.0后,删除接口返回204状态码时触发“Response content longer than Content-Length”错误,核心原因是HTTP 204规范要求响应不能包含任何内容体,但你的代码里返回了JSONResponse({}, status_code=204)——空对象{}经过JSON序列化后仍是有长度的内容,新版本框架对HTTP规范的校验更严格,因此抛出错误。
解决方案
直接返回不带内容体的Response对象,替代JSONResponse:
核心修改点
将原返回JSONResponse的逻辑,根据状态码分支处理:当状态码为204时,返回无内容体的Response;其他状态码正常返回JSONResponse。
修改后代码示例
from fastapi import APIRouter, Depends, status, Response, BackgroundTasks, Request def delete_assessment(response: Response, request : Request, background_tasks: BackgroundTasks, header: Header = Depends(HeaderParams), params: DeleteAssessmentArgs = Depends(DeleteAssessmentArgs) ): response_obj = { 'response_code': status.HTTP_204_NO_CONTENT, 'response_obj': {} } try: dao = AssessmentRequestDao() response_obj = dao.delete_assessment(params.assessment_id, params.is_delete_with_submitted_Responses, background_tasks, request) # 添加后台任务 deleted_assessment = response_obj['response_obj']['categories'][0] event_type = AssessmentEventTypes.Deleted endpoint = AssessmentEndPoint.Assessment if response_obj['response_code'] == 204: background_tasks.add_task( onestream_publish_service.send_business_event, request.headers.get('Correlation-Id'), params.assessment_id, endpoint, deleted_assessment, event_type ) # 按状态码返回对应响应 if response_obj['response_code'] == status.HTTP_204_NO_CONTENT: return Response(status_code=status.HTTP_204_NO_CONTENT) else: return JSONResponse(response_obj['response_obj'], status_code=response_obj['response_code']) except Exception as e: logger.exception(e) # 异常场景同样按状态码处理 if response_obj['response_code'] == status.HTTP_204_NO_CONTENT: return Response(status_code=status.HTTP_204_NO_CONTENT) else: return JSONResponse(response_obj['response_obj'], status_code=response_obj['response_code'])
额外说明
- HTTP 204的定义就是“无内容”,任何包含响应体的返回都不符合规范,新版本框架收紧校验才暴露了这个潜在问题。
- 后台任务的执行不受影响,FastAPI会在返回响应后才运行已添加的后台任务,只要在返回响应前完成任务添加即可。
内容的提问来源于stack exchange,提问作者user15772986
相关产品推荐
相关产品推荐

