Flask模板内嵌JS正常,移至独立文件后出现JSON解析错误
Flask静态JS文件中Jinja模板变量解析失败问题解决
问题重现
将Flask模板中内嵌的JS代码移至static/reserve.js独立文件后,Chrome控制台抛出错误:
Uncaught SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2) at JSON.parse (<anonymous>) at reserve.js:1:21
错误指向reserve.js第一行的var day_list = JSON.parse('{{ day_list|tojson }}');,该变量由Python后端传递至模板,内嵌JS时可正常运行。
核心原因
Flask仅会渲染templates目录下的模板文件,static目录下的JS文件属于静态资源,会直接返回给浏览器,不会处理其中的Jinja模板语法。因此{{ day_list|tojson }}不会被替换为实际的JSON字符串,而是原样作为文本传递给JSON.parse,导致解析失败。
解决方案
在HTML模板中通过全局变量注入数据,再让静态JS文件读取该全局变量,具体步骤如下:
1. 修改reserve.html,注入全局变量
在引入静态JS文件前,添加<script>标签将day_list注入到window全局对象:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Make a reservation</h1> <h2>Choose a day:</h2> <!-- 先通过模板渲染注入全局变量 --> <script> window.day_list = {{ day_list|tojson }}; </script> <!-- 再引入静态JS文件 --> <script src="{{ url_for('static', filename='reserve.js') }}"></script> {% for day in day_list %} <form id="{{ day.order }}" method="POST"> <input type="button" id="{{ day.num }}" onclick="today(button_id='{{ day.num }}', div_id='{{ day.name }}')" value="{{ day.num }}" style="background-color: white;" > <div id="{{ day.name }}" style="display: none;"> <label>Hello</label> </div> </form> {% endfor %} </body> </html>
2. 修改static/reserve.js,使用全局变量
移除原有的JSON.parse代码,直接读取全局的window.day_list:
// 直接使用全局注入的变量 var day_list = window.day_list; function today(button_id, div_id) { var button = document.getElementById(button_id); var div = document.getElementById(div_id); if (div.style.display == "block") { div.style.display = "none"; button.style.backgroundColor = "white"; } else { div.style.display = "block"; button.style.backgroundColor = "blue"; } for (const day in day_list) { if (day_list[day].num != button_id) { document.getElementById(day_list[day].num).style.backgroundColor = "white"; document.getElementById(day_list[day].name).style.display = "none"; } } } for (const day in day_list) { console.log(day_list[day]); }
说明
{{ day_list|tojson }}会被Flask渲染为合法的JS对象格式,无需额外使用JSON.parse解析- 全局变量注入方式既保持了JS文件的独立性,又能正常获取后端传递的数据
内容的提问来源于stack exchange,提问作者Aya Noaman
相关产品推荐
相关产品推荐

