Django模板中如何正确批量将渲染变量赋值给JavaScript变量
当前规范下DOM传值的正确写法
你之前用自定义<state>标签存值的写法是XHTML时代的兼容方案,放到现在的HTML5规范下并不推荐:HTML5虽然支持自定义元素,但要求自定义元素必须通过customElements.define注册、且标签名必须带短横线(比如<my-state>),无注册的无短横线自定义标签不符合语义规范,也没有实际使用价值。
不需要专门用空<div>存值,更合理的写法分两种场景:
- 如果是全局通用的页面变量,直接把
data-*属性挂在<body>或者<html>根节点上,不会产生冗余DOM节点,比如<body data-state="{{ state|escapejs }}"> - 如果变量是和某个页面组件强绑定的(比如表单初始值、组件配置),直接把
data-*属性挂在对应组件的根DOM节点上即可,比如选择框的初始值直接写在<select>标签上,不需要额外加空标签。
所有现代浏览器都原生支持datasetAPI读取data-*属性,不需要写冗长的getAttribute,比如读取上面的state值直接用document.body.dataset.state即可。
Django模板批量传值到JS的实用方案
零散写<script>var state = '{{ state }}'</script>的方式维护性差,还容易因为未转义特殊字符引发JS报错或者XSS漏洞,批量传值推荐下面三个经过生产验证的方案:
- 方案1:用Django自带的
json_script标签统一传值(官方推荐,安全性最高)
Django 2.1及以上版本内置了json_script过滤器,会自动把Python对象序列化成转义后的JSON,生成一个type="application/json"的隐藏script标签,完全规避XSS风险。
你只需要在视图层把所有需要传给前端的变量打包成一个字典,比如page_config = {"state": state, "user_id": request.user.id, "is_vip": is_vip},传到模板后只需要写一行代码:
前端JS里只需要一次解析就能拿到所有变量:{{ page_config|json_script:"page-config" }}
后续新增变量只需要在视图层往const pageConfig = JSON.parse(document.getElementById('page-config').textContent); // 直接通过pageConfig.state、pageConfig.user_id访问所有变量page_config字典里加字段即可,不需要修改模板代码,维护成本极低。 - 方案2:批量生成根节点data属性
如果变量数量不多,可以直接在模板里循环渲染<body>标签的data属性,不需要额外加标签:
前端直接读<body {% for key, val in frontend_vars.items %} data-{{ key }}="{{ val|escapejs }}" {% endfor %} >document.body.dataset就能拿到所有键值对,不需要逐个写属性名。 - 方案3:配置接口拉取
如果需要传递的变量数量特别多,或者页面加载后需要动态更新配置,可以单独写一个返回JSON格式配置的接口,页面初始化时JS通过请求拉取全量配置即可,模板层不需要写任何变量传递逻辑,适合中大型半分离项目。
注意:无论用哪种方案,都不要直接把模板变量裸插到JS字符串里,必须用
escapejs或者json_script做转义,避免变量里的单引号、尖括号、特殊字符引发语法错误或者XSS攻击。
内容的提问来源于stack exchange,提问作者anjanesh
相关产品推荐
相关产品推荐

