如何将Django模板中的Ajax脚本迁移至独立JS文件运行?
解决Django中独立JS文件无法运行AJAX脚本的问题
问题根源
静态JS文件不会经过Django模板引擎渲染,你原代码里的{% url "add_cart" %}和{{csrf_token}}会以原始字符串形式返回给浏览器,导致AJAX请求的URL无效、CSRF验证失败,这就是脚本失效的核心原因。
解决方案1:模板定义全局变量传递动态值
在模板中引入独立JS文件之前,把需要的动态数据定义为全局变量,让JS文件可以直接读取:
- 修改模板代码(在引入
my_js.js前添加):
<script> // 存储Django模板生成的动态值 window.cartConfig = { addCartUrl: "{% url 'add_cart' %}", csrfToken: "{{ csrf_token }}" }; </script> <script src="{% static 'js/my_js.js' %}"></script>
- 调整
my_js.js代码:
$(document).on('click', '#add-button', function (e){ e.preventDefault(); var prodid = $(this).val(); // 用$(this)获取当前点击按钮的值,避免多按钮场景出错 $.ajax({ type: 'POST', url: window.cartConfig.addCartUrl, data: { product_id: prodid, quantity: $('#qty').val(), csrfmiddlewaretoken: window.cartConfig.csrfToken, action: 'POST' }, success: function (json) { document.getElementById('cart_icon_count').innerHTML = json.qty; }, error: function(xhr, errmsg, err) {} }); })
解决方案2:用HTML数据属性存储动态值
把动态值绑定到触发AJAX的元素上,JS通过data-*属性读取:
- 修改模板中的按钮:
<button id="add-button" data-add-url="{% url 'add_cart' %}" data-csrf="{{ csrf_token }}" value="{{ product.id }}"> 添加到购物车 </button>
- 调整
my_js.js代码:
$(document).on('click', '#add-button', function (e){ e.preventDefault(); var $btn = $(this); $.ajax({ type: 'POST', url: $btn.data('add-url'), data: { product_id: $btn.val(), quantity: $('#qty').val(), csrfmiddlewaretoken: $btn.data('csrf'), action: 'POST' }, success: function (json) { document.getElementById('cart_icon_count').innerHTML = json.qty; }, error: function(xhr, errmsg, err) {} }); })
额外优化:统一处理CSRF令牌
可以不用每次在AJAX数据里手动传CSRF令牌,在模板中添加全局AJAX配置:
<script> $.ajaxSetup({ headers: { "X-CSRFToken": "{{ csrf_token }}" } }); </script>
之后JS文件里的AJAX请求可以直接去掉csrfmiddlewaretoken字段,简化代码。
内容的提问来源于stack exchange,提问作者Serhio
相关产品推荐
相关产品推荐

