You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django表单多文件上传生产环境遇CSRF Forbidden 403问题求助

Django + Heroku + Cloudflare 上传功能 CSRF 403/400 错误排查方案

先定位400错误根源(直接访问Heroku域名的情况)

400 Bad Request通常是请求格式、header或配置不匹配导致的,优先查看Heroku日志获取具体错误信息:

  • 执行命令查看实时日志:heroku logs --tail
  • 日志中会明确给出400的原因,比如CSRF cookie not set、Referer checking failed、Invalid CSRF token或Request body too large等,这是最关键的排查依据。

核心配置检查(Django settings.py)

  • CSRF_TRUSTED_ORIGINS:必须包含你的Cloudflare自定义域名和Heroku域名,格式要带完整协议(http/https):
    CSRF_TRUSTED_ORIGINS = [
        "https://your-custom-domain.com",
        "https://your-heroku-app.herokuapp.com"
    ]
    
  • ALLOWED_HOSTS:确保包含两个域名,Heroku环境下可以直接指定:
    ALLOWED_HOSTS = ["your-custom-domain.com", "your-heroku-app.herokuapp.com"]
    
  • 安全Cookie设置:生产环境下需开启以下选项,同时确保Cloudflare SSL模式为Full/Full (Strict):
    SECURE_SSL_REDIRECT = True
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
    
    若Cloudflare用Flexible SSL,会导致Heroku收到HTTP请求,此时需暂时关闭SECURE_SSL_REDIRECT测试,但不推荐长期使用Flexible模式。

Cloudflare 相关排查

  • SSL模式:设置为Full或Full (Strict),避免Flexible模式导致的HTTP/HTTPS不兼容问题。
  • 缓存与优化:
    • 对表单提交路径(如/upload/)设置Page Rules,将Cache Level设为Bypass,禁止Cloudflare缓存请求内容。
    • 暂时关闭Auto Minify和Rocket Loader,这些功能可能篡改页面中的CSRF token或请求头。
  • HTTP头修改:检查Cloudflare是否添加了额外的头(如CF-Connecting-IP),Django默认会信任这些头,但如果有自定义中间件,需确保不会干扰CSRF验证。

表单与请求验证

  • 表单基础检查:
    • 确认表单标签内包含method="POST"和enctype="multipart/form-data",拼写无错误。
    • {% csrf_token %}必须放在<form>标签内部,未被JS或其他元素遮挡。
  • 请求头与Token验证:
    用浏览器开发者工具(Network面板)查看提交请求:
    • 检查Form Data中是否存在csrfmiddlewaretoken字段,且值与页面中的隐藏input一致。
    • 检查Cookie中是否有csrftoken,若不存在,说明Django未正确设置Cookie,需排查域名匹配问题。
  • AJAX提交特殊处理:
    若用AJAX上传文件,需手动携带CSRF token,且不要手动设置Content-Type(浏览器会自动添加正确的boundary):
    const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
    const formData = new FormData(document.getElementById('upload-form'));
    
    fetch('/upload/', {
      method: 'POST',
      headers: { 'X-CSRFToken': csrfToken },
      body: formData
    });
    

csrf_exempt后仍400的排查方向

此时问题已与CSRF无关,重点检查:

  • 文件大小限制:
    • Django的DATA_UPLOAD_MAX_MEMORY_SIZE默认是2.5MB,若上传文件过大,需调整该值:
      DATA_UPLOAD_MAX_MEMORY_SIZE = 52428800  # 50MB
      
    • Heroku平台默认请求大小限制为30MB,若文件超过此值,需联系Heroku升级或优化文件内容。
  • 视图逻辑错误:
    • 检查视图中是否正确处理request.FILES,比如判断文件是否存在:
      file = request.FILES.get('file')
      if not file:
          return HttpResponseBadRequest("No file uploaded")
      
    • 确保内存处理逻辑未抛出异常,比如解析TXT坐标时的格式错误,未被捕获导致返回400。

内容的提问来源于stack exchange,提问作者diml

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:48:18