Django项目中JS发送PUT请求调用API返回403 Forbidden如何解决
Django fetch请求返回403错误解决方案
原因说明
Django默认会对所有POST、PUT、DELETE等修改类请求做CSRF校验,普通表单提交时框架会自动插入csrf token并校验,但是通过JavaScript手动发起的fetch请求不会自动携带该token,因此触发403权限拦截。
解决步骤
- 第一步:编写获取CSRF token的工具函数,Django的csrf token默认存储在名为
csrftoken的Cookie中:
function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken');
- 第二步:在PUT请求的配置项中添加请求头,传入获取到的csrf token,同时指定内容类型为JSON:
注意修正原代码中body里固定写死likes:2的问题,替换为计算得到的newamount。
fetch(`/posts/${id}`, { method: 'PUT', headers: { 'X-CSRFToken': csrftoken, 'Content-Type': 'application/json' }, body: JSON.stringify({ likes: newamount }) })
完整修改后代码参考
// 工具函数,获取csrf token function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); document.addEventListener('DOMContentLoaded', () => { document.querySelector("#like").addEventListener('click', () => { var num = document.querySelector("#like").value; addlike(num) }) }) const addlike = id => { console.log("Ran") fetch(`/posts/${id}`) .then(res => res.json()) .then(post => { var newamount = post.likes + 1; fetch(`/posts/${id}`, { method: 'PUT', headers: { 'X-CSRFToken': csrftoken, 'Content-Type': 'application/json' }, body: JSON.stringify({ likes: newamount }) }) }) }
内容的提问来源于stack exchange,提问作者Rasax Zero
相关产品推荐
相关产品推荐

