
在 Flask + Chart.js 项目中,直接将 Python 列表(如 ['test1', 'test2'])通过 {{ labels }} 插入 JavaScript 会导致 HTML 实体转义错误(如 &),正确做法是使用 Jinja 的 |tojson 过滤器安全序列化数据。
在 flask + chart.js 项目中,直接将 python 列表(如 `['test1', 'test2']`)通过 `{{ labels }}` 插入 javascript 会导致 html 实体转义错误(如 `&`),正确做法是使用 jinja 的 `|tojson` 过滤器安全序列化数据。
在 Chart.js(v4+)中,labels 并非 dataset 的属性,而是顶层 data 对象的直属字段。你当前的写法:
datasets: [{
type: 'scatter',
labels: {{ labels }}, // ❌ 错误:labels 不属于 dataset
data: {{ data }}
}]不仅语义错误(Chart.js 会忽略该字段),更关键的是:当 Jinja 渲染 {{ labels }} 时,若 labels = ['test1', 'test2'],默认输出为 ['test1', 'test2'] —— 表面看似合法,但 Flask 的 Jinja 模板引擎默认会对输出内容进行 HTML 转义(例如将
✅ 正确解法:使用 |tojson 过滤器
该过滤器由 Flask/Jinja 内置提供,能将 Python 对象(列表、字典、字符串等)安全、无转义地序列化为标准 JSON 字符串,并自动处理引号、Unicode 和特殊字符,生成可直接被 JavaScript 解析的有效字面量。
✅ 正确代码结构(Chart.js v4+ 推荐模式)
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="myChart"></canvas>
<script>
// ✅ 使用 |tojson 确保 JSON 安全注入
const chartData = {
labels: {{ labels | tojson }}, // ? 正确位置:data.labels
datasets: [
{
label: 'Line Trend',
type: 'line',
data: [],
backgroundColor: 'rgb(168, 38, 8)',
borderColor: 'rgb(168, 38, 8)',
pointRadius: 0,
borderWidth: 3,
order: 2
},
{
label: 'Red Points',
type: 'scatter',
data: [],
backgroundColor: 'rgb(168, 38, 8)',
borderColor: 'rgb(168, 38, 8)',
pointRadius: 3,
order: 3
},
{
label: 'Green Points',
type: 'scatter',
data: [],
backgroundColor: 'rgb(46, 179, 84)',
borderColor: 'rgb(46, 179, 84)',
pointRadius: 3,
order: 1
},
{
label: 'Blue Labels',
type: 'scatter',
data: {{ data | tojson }}, // ? 数据也需 tojson
backgroundColor: 'rgb(52, 110, 235)',
borderColor: 'rgb(52, 110, 235)',
pointRadius: 1,
order: 4
}
]
};
const config = {
type: 'scatter',
data: chartData, // ? 整个 chartData 作为 data 传入
options: {
maintainAspectRatio: true,
aspectRatio: 1,
events: [],
plugins: {
legend: { display: false }
},
scales: {
x: { display: false },
y: { display: false }
}
}
};
const myChart = new Chart(document.getElementById('myChart'), config);
</script>⚠️ 关键注意事项
labels 必须位于 data 根对象下,而非某个 dataset 内:Chart.js 的 scatter、line、bar 等图表类型均要求 labels 与 datasets 同级(参考 官方文档)。
所有动态数据都应统一使用 |tojson:包括 data、labels、options 中的动态配置项(如 title.text),避免部分转义、部分未转义导致语法不一致。
-
确保后端传递的是合法 Python 对象:Flask 视图中应传递原生 list 或 dict,而非 JSON 字符串:
# ✅ 正确(Python list) return render_template('chart.html', labels=['test1', 'test2'], data=[{x:1,y:2}, {x:3,y:4}]) # ❌ 错误(字符串会被双引号包裹,JSON.parse 失败) # labels=json.dumps(['test1','test2']) 无需额外引入 json 库或手动 JSON.parse():|tojson 输出即为 JS 可执行字面量(如 ["test1","test2"]),直接赋值即可。
✅ 验证是否生效
在浏览器开发者工具中查看渲染后的 HTML 源码,确认 labels 行类似:
labels: ["test1", "test2", "test3"],
而非:
labels: ['test1', 'test2', 'test3'], // ❌ 可能被转义为 '
或包含 "、& 等实体字符。
遵循此模式,即可彻底规避模板注入语法错误,实现 Flask 与 Chart.js 之间安全、健壮的数据传递。










