使用Fetch发送FormData时Django CSRF验证失败求助
更新 #1 – 2023年7月26日
根据@thebjorn的评论,尝试设置Content-Type: 'application/x-www-form-urlencoded'并将token名称设为csrfmiddlewaretoken,但错误仍存在。
以下是测试过的实现方式,供参考:
- 直接在请求头中添加CSRF Token和Content-Type:
headers: new Headers({ 'Content-Type' : 'application/x-www-form-urlencoded', 'csrfmiddlewaretoken': csrftoken })
- 将token附加到表单数据:
coverPhotoForm.append('csrfmiddlewaretoken') - 同时包含
csrfmiddlewaretoken和X-CSRFToken(看似冗余但仍做了测试)。
原始问题
我尝试使用JavaScript的fetch发送POST请求,向Django接口提交动态创建的包含图片的FormData对象,但始终无法正确附加CSRF Token,导致出现CSRF token missing错误。
按照Django CSRF相关规范,我已在settings.py中设置CSRF_COOKIE_HTTPONLY = True,并在HTML文件中添加了隐藏的{% csrf_token %},然后在JavaScript中尝试获取该Token:
// 创建表单用于上传图片 let coverPhotoForm = new FormData(); // 从DOM中读取CSRF Token和图片文件 const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; const coverPhotoUpload = document.querySelector('#cover-photo-upload'); // 向表单对象添加CSRF Token和图片 coverPhotoForm.append('X-CSRFToken', csrftoken) coverPhotoForm.append('cover_photo', coverPhotoUpload.files[0]); // 通过POST请求上传图片到接口 fetch(`/profile/${profileUserId}`, { method: 'POST', body: coverPhotoForm, mode: 'same-origin' }) .then( response => response.json()) .then( response => { console.log(response) }) })
注意事项
- 通过
console.log验证,csrftoken已成功从DOM中读取。 - 页面刷新后图片能上传成功,但每次发送请求时都会出现
CSRF token missing错误。
我还尝试直接在fetch请求中设置请求头,以及参考Django官方示例,均无效果:
const request = new Request( fetch(`/profile/${profileUserId}, { method: 'POST', headers: {'X-CSRFToken': csrftoken}, mode: 'same-origin' } );
额外尝试
- 上述实现改编自Stack Overflow的已采纳答案。
- 尝试在请求的
headers字典中添加accept和content-type字段。 - 为视图函数添加
@ensure_csrf_cookie装饰器,符合Django文档中动态创建表单的建议。 - 使用
csrfmiddlewaretoken: '{{ csrf_token }}'代替通过querySelector从DOM读取Token。
内容的提问来源于stack exchange,提问作者DAK
相关产品推荐
相关产品推荐

