已使用csrf_token和CSRF_TRUSTED_ORIGINS仍CSRF验证失败,如何提交表单?
解决Django个人资料表单提交失败问题
问题概述
提交个人资料修改表单时出现CSRF验证失败,同时文件上传字段无法正常工作,已使用{% csrf_token %}标签并配置CSRF_TRUSTED_ORIGINS。
核心问题分析
- 重复CSRF令牌输入:模板中手动添加了空的
csrfmiddlewaretoken隐藏字段,覆盖了{% csrf_token %}生成的有效令牌,导致验证失败。 - 缺少文件上传编码类型:表单包含文件上传字段(
avatar),但未设置enctype="multipart/form-data",导致表单数据解析错误,间接影响CSRF验证。 - 视图未处理文件数据:POST请求处理时未传入
request.FILES,即使表单配置正确,文件也无法保存。
分步修复
1. 修复模板表单
移除多余的空CSRF字段,添加文件上传编码类型,同时给名称输入框填充当前值:
{% if user.is_authenticated %} <p>Thong tin nguoi dung:</p> <a>Ten nguoi dung: {{profile.name}}</a> <p>Anh dai dien: <img src="{{profile.avatar.url}}" alt=""></p> <form action="{% url 'users:profile'%}" method="post" enctype="multipart/form-data"> {% csrf_token %} <p> <label for="id_name">Name:</label> <input type="text" name="name" maxlength="200" required="" id="id_name" value="{{ profile.name }}"> </p> <p> <label for="id_avatar">Avatar:</label> <input type="file" name="avatar" accept="image/*" id="id_avatar"> </p> <button name="submit">save changes</button> </form> {% else %} {% endif %}
2. 更新视图处理文件上传
在表单初始化时传入request.FILES,确保文件字段能获取到上传内容:
@login_required def profile(request): """Show profile""" profile = UserProfile.objects.get(user=request.user) if request.method != 'POST': # No data submitted; create a blank form. form = UserProfileForm(instance=profile) else: # POST data submitted; process data. form = UserProfileForm(instance=profile, data=request.POST, files=request.FILES) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('base:index')) context = {'profile': profile, 'form': form} return render(request, 'users/profile.html', context)
3. 验证CSRF信任源配置(可选)
如果本地开发使用非80端口(如默认的8000),需在settings.py中补充端口号:
CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1:8000']
额外检查项
- 确保浏览器未禁用Cookie,Django的CSRF验证依赖Cookie存储令牌
- 清除浏览器缓存和Cookie后重新测试
内容的提问来源于stack exchange,提问作者Van Phong
相关产品推荐
相关产品推荐

