You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:03:33