You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

FastAPI文件上传经API Gateway/CloudFront/NGINX路由链后出现空白/损坏问题求助

FastAPI文件上传经API Gateway/CloudFront/NGINX路由链后出现空白/损坏问题求助

兄弟,我之前也碰到过类似跨路由链的文件上传损坏问题,结合你给出的日志和测试数据,大概率是路由链上某个环节对二进制内容的处理出了问题,咱们一步步来分析和排查:

先看你给出的关键差异数据,这是定位问题的核心:

  • 内部请求:FastAPI收到的文件是30176字节,NGINX日志里请求总大小30650字节,完全正常
  • 外部请求:FastAPI收到的文件只剩5758字节,NGINX日志里请求总大小才1048字节,明显是内容被截断或转码损坏了

最可能的原因及对应排查/解决步骤

1. API Gateway 未配置二进制媒体类型(最可能的元凶)

API Gateway默认会把所有请求当成纯文本处理,如果你的multipart/form-data里包含二进制文件,它会强制把二进制内容转成UTF-8文本,直接导致二进制损坏、内容截断。

排查&解决:

  • 登录AWS控制台,找到你的API Gateway实例,进入「Settings」页面
  • 在「Binary Media Types」里添加 multipart/form-dataapplication/pdf(测试阶段可以临时加*/*,生产环境建议精准匹配)
  • 重新部署你的API,然后立即测试外部上传

2. CloudFront 压缩/转发设置异常

CloudFront如果开启了自动压缩,可能会误把二进制PDF或multipart表单当成文本压缩,导致内容损坏;另外如果没有正确转发必要请求头,后端也无法正确解析表单结构。

排查&解决:

  • 进入CloudFront控制台,找到对应API的「Behaviors」规则
  • 关闭「Compress Objects Automatically」(至少针对/document/upload这个路径的独立行为)
  • 确认「Allowed HTTP Methods」包含POST请求
  • 把「Forward Headers」设置为「AllViewer」,或至少包含Content-TypeContent-LengthTransfer-Encoding
  • 保存后等待CloudFront配置生效(约10-15分钟)再测试

3. NGINX 配置仍有遗漏(虽然你调整了大小,但还有隐藏坑)

你已经调整了大文件支持,但可能还有几个关键配置没到位,导致请求转发时损坏:

建议修改NGINX的location配置块为:

location /document/upload {
    client_max_body_size 100M;  # 确保足够覆盖你的文件+表单总大小
    proxy_request_buffering off;  # 关闭请求缓冲,直接转发给后端,避免大文件截断
    proxy_buffering off;  # 关闭响应缓冲,同理
    proxy_http_version 1.1;  # 强制用HTTP/1.1转发,和后端FastAPI兼容
    proxy_set_header Connection "";  # 配合HTTP/1.1,避免长连接头冲突
    proxy_set_header Host $host;  # 正确传递请求Host头
    proxy_set_header X-Real-IP $remote_addr;  # 可选,方便日志溯源
    
    proxy_pass http://doc-service.default.svc.cluster.local:8500;
}

临时调试技巧:
在上述location块里添加client_body_in_file_only on;,NGINX会把收到的请求体保存到/var/lib/nginx/body/目录的临时文件中:

  • 如果临时文件大小和你本地的test.pdf+表单数据总大小一致,说明问题出在NGINX转发给FastAPI的环节
  • 如果临时文件大小明显偏小,说明请求到达NGINX之前就已经被截断/损坏,问题出在CloudFront/API Gateway/ALB

4. ALB 请求大小限制(兜底排查)

虽然你的测试文件只有30KB,ALB默认1MB的限制应该足够,但保险起见还是检查:

  • 进入AWS EC2控制台,找到你的ALB,进入「Listeners」页面编辑对应监听器
  • 检查「Default action」的「Forward」配置,确认「Request body size constraint」设置足够大(比如100MB)

快速定位问题的后端调试技巧

你可以在FastAPI里加一个临时调试接口,直接验证收到的请求体是否完整:

from fastapi import FastAPI, Request

app = FastAPI()

# 临时调试接口,生产环境记得删除
@app.post("/debug-upload")
async def debug_upload(request: Request):
    body = await request.body()
    print(f"收到的请求体总大小: {len(body)} 字节")
    print(f"前100字节内容: {body[:100]}")
    # 可选:把收到的内容保存到本地对比
    with open("/tmp/debug-received.bin", "wb") as f:
        f.write(body)
    return {"received_size": len(body)}

分别用内部和外部请求调用这个接口:

  • 内部调用返回的大小和本地文件+表单总大小一致 → 后端逻辑没问题
  • 外部调用返回的大小明显偏小 → 请求在到达FastAPI前就已损坏

最后总结

从你的NGINX日志来看,外部请求的大小被砍到1048字节,大概率是API Gateway未配置二进制支持导致的,先从这个点入手,应该能直接解决问题。如果还不行,再按CloudFront → NGINX → ALB的顺序排查,肯定能找到问题环节!

火山引擎 最新活动