Django中使用AJAX添加商品到购物车出现CSRF错误如何解决?
问题解决方案
错误原因
Django默认对所有POST请求做CSRF安全校验,你当前的AJAX请求没有携带表单里的CSRF令牌,因此触发了403 Forbidden拦截,请求被拒绝后商品自然无法添加到购物车。
修复步骤
1. 修正AJAX代码,携带表单数据和CSRF令牌
你原有代码仅配置了请求地址,没有提交表单内的CSRF令牌、商品数量等核心数据,替换为如下代码即可:
$(document).on("click",".Id_submit",function(event){ event.preventDefault(); var selector = $(this).closest(".productID"); var form = selector.find("form"); // 序列化表单所有数据,自动包含CSRF令牌和商品数量字段 var formData = form.serialize(); $.ajax({ type : 'POST', url: form.attr('action'), data: formData, success: function() { alert("商品已成功添加到购物车") } }); });
2. 补充HTML表单的提交地址
你原有form标签未指定action提交路径,需要补上购物车新增接口的路由:
<form id='transactionIDValue' class="d-inline" method="post" action="{% url 'cart_add' product.id %}"> {{cart_product_form}} {% csrf_token %} <input type="submit" class="btn btn-primary shadow px-5 py-2 Id_submit" value="加入购物车"> </form>
注意替换代码中的product.id为你模板内实际对应的商品ID变量名。
3. 修复路径重复问题
你报错的请求路径为/cart/add/add/carts/16/,存在add前缀重复的问题,检查根路由配置:如果根路由引入购物车应用时已经加了add/前缀,可以把购物车应用内urls.py的外层add/路径删除,避免重复。
可选配置:全局AJAX自动携带CSRF令牌
如果项目内有多处AJAX POST请求,可以加这段全局配置,无需每个请求单独传CSRF参数:
$.ajaxSetup({ beforeSend: function(xhr, settings) { 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; } // 仅给本地请求添加CSRF头 if (!/^http:.*/.test(settings.url) && !/^https:.*/.test(settings.url)) { xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); } } });
额外排查建议
如果修复CSRF问题后商品仍然无法添加,可以在views.py的if form.is_valid()前加一行print(form.errors),查看控制台输出的表单校验错误,通常是商品数量字段传值不符合要求导致的。
内容的提问来源于stack exchange,提问作者Muhammad Usama Naveed
相关产品推荐
相关产品推荐

