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):
若Cloudflare用Flexible SSL,会导致Heroku收到HTTP请求,此时需暂时关闭SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = TrueSECURE_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,需排查域名匹配问题。
- 检查Form Data中是否存在
- 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升级或优化文件内容。
- Django的
- 视图逻辑错误:
- 检查视图中是否正确处理
request.FILES,比如判断文件是否存在:file = request.FILES.get('file') if not file: return HttpResponseBadRequest("No file uploaded") - 确保内存处理逻辑未抛出异常,比如解析TXT坐标时的格式错误,未被捕获导致返回400。
- 检查视图中是否正确处理
内容的提问来源于stack exchange,提问作者diml
相关产品推荐
相关产品推荐

