在 Jinja 模板中安全、规范地向外部 JavaScript 文件传递变量

jinja 变量无法直接在外部 js 文件中渲染,需通过内联 `

在 Flask、Django(Jinja2 后端)等模板驱动的 Web 应用中,开发者常需将服务端动态数据(如用户 ID、配置项、API 路径)传递给前端 JavaScript 逻辑。虽然 {{ var }} 在内联

✅ 正确实践:分层注入 + 作用域桥接
核心思路是:在 HTML 模板中,先用内联 。外部 JS 可直接访问该变量,无需额外通信机制。

示例代码如下:



  

Hello, {{ user.name }}!

// static/js/app.js
console.log('User ID:', APP_CONFIG.userId);        // ✅ 正常输出
console.log('API endpoint:', APP_CONFIG.apiUrl);   // ✅ 字符串自动加引号
console.log('Features:', APP_CONFIG.features);       // ✅ 支持数组、对象、布尔值、null

⚠️ 重要注意事项:

  • 务必使用 | tojson 过滤器(Jinja2 内置):它会自动转义特殊字符、添加引号,并保证输出合法的 JSON,避免 XSS 风险和语法错误。切勿直接写 {{ var }}(尤其当 var 是字符串时易引发 JS 解析失败)。
  • 避免污染全局命名空间:建议将多个变量封装进单一命名对象(如 APP_CONFIG),而非声明多个全局变量,便于维护和 Tree-shaking(若后续接入模块打包)。
  • 加载顺序不可颠倒
  • 不推荐使用 window.xxx = ... 显式挂载:现代 JS 更倾向模块化与作用域控制;若需兼容旧代码,可显式赋值,但仍建议优先使用 const 声明 + 模块内引用。

? 进阶提示:对于大型应用,可结合 data-* 属性 + document.currentScript 或自定义事件进一步解耦,但对绝大多数场景,上述“预定义全局对象”方案已足够简洁、安全且可扩展。