如何在Django与JavaScript间传递CSRF Token?GeoDjango+Leaflet问题
解决Leaflet uGeoJSON Layer无法获取CSRF Token导致403的问题
核心问题原因
你的代码中token和header始终为null,是因为Django模板未输出对应的CSRF meta标签,导致jQuery无法定位到这些元素获取值,最终请求因缺少合法CSRF头被Django的CSRF保护机制拦截,返回403错误。
解决方案步骤
1. 在Django模板的<head>中添加CSRF Meta标签
在引入map.js的模板文件里,找到<head>区域,添加以下代码:
<meta name="_csrf" content="{{ csrf_token }}"> <meta name="_csrf_header" content="X-CSRFToken">
Django会自动将{{ csrf_token }}替换为当前有效的CSRF令牌值,X-CSRFToken是Django默认识别的CSRF请求头名称。
2. 确保jQuery在map.js之前加载
你的代码依赖jQuery获取meta标签,必须先加载jQuery,再引入地图脚本。调整模板中的脚本加载顺序:
<!-- 先加载jQuery --> <script src="{% static 'path/to/jquery.min.js' %}"></script> <!-- 再加载你的地图脚本 --> <script src="{% static 'core/map.js' %}"></script>
如果没有本地jQuery文件,也可以使用CDN链接:
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
3. 修正Endpoint路径(可选但推荐)
endpoint: "data.jobs/"的相对路径可能存在嵌套页面时的路径错误,建议使用Django的URL反向解析生成绝对路径:
<!-- 在模板中先定义路径变量 --> <script> var jobsEndpoint = "{% url 'your-jobs-data-view-name' %}"; </script> <!-- 再引入map.js --> <script src="{% static 'core/map.js' %}"></script>
然后在map.js中修改配置:
DmseJobData = new L.uGeoJSONLayer({ endpoint: jobsEndpoint, // 其他配置项... }),
将your-jobs-data-view-name替换为你在urls.py中定义的通用类视图的URL名称。
4. 验证CSRF头是否正确获取
修改map.js添加调试输出,确认token值是否正常获取:
var headers = {}; // CSRF headers var token = jQuery("meta[name='_csrf']").attr("content"); var header = jQuery("meta[name='_csrf_header']").attr("content"); // 调试输出,检查值是否有效 console.log("CSRF Token:", token); console.log("CSRF Header:", header); if (header && token) { // 同时校验两个值的有效性 headers[header] = token; }
打开浏览器开发者工具控制台,查看输出是否有合法的token值,确认获取成功后,请求就会携带正确的CSRF头。
额外注意事项
- 确保
django.middleware.csrf.CsrfViewMiddleware中间件在settings.py的MIDDLEWARE列表中(默认已启用)。 - 通用类视图无需添加
@csrf_exempt装饰器,只要请求携带合法CSRF头即可正常处理。
内容的提问来源于stack exchange,提问作者Andrew Toole
相关产品推荐
相关产品推荐

