Jinja模板向JavaScript传递字典值异常:无法正确解析为对象
问题:Jinja模板下拉框切换时无法正确获取对应图片路径
在Jinja模板中实现尺寸下拉选择框,切换选项时想显示字典中对应的图片,但将完整字典传递给JavaScript函数后,JS把它识别为字符串而非对象,遍历输出单个字符,导致result['size_image']返回undefined,图片加载失败。
模板代码
<div class="single-product-form"> <form action="index.html"> <label for="size">Choose size</label> <select name="colours" onchange="displayTryImg(this)"> {% for sizekey, sizevalue in product.sizes.items() %} <option value="{{ sizevalue }}" SELECTED>{{ sizevalue.product_size }}</option> {% endfor %} </select> <div class="tray-image"><img id="tray-img" src=""></div> </form> </div>
JavaScript代码
function displayTryImg(size){ var result = size.value; console.log('result '+result) for(var key in result){ console.log('val : '+result[key]) // 输出单个字符而非对象属性 } document.getElementById("tray-img").src="/static/images/"+result['size_image']; // 返回undefined }
控制台输出
result {'size_id': 3, 'product_size': 'Medium Tray', 'product_quantity': 2, 'size_description': 'Medium Tray usually enough for 3 people', 'size_image': 'tray.jpg'} custom.js:76 val : { custom.js:76 val : ' custom.js:76 val : s custom.js:76 val : i custom.js:76 val : z custom.js:76 val : e custom.js:76 val : _ custom.js:76 val : i custom.js:76 val : d custom.js:76 val : ' custom.js:76 val : : custom.js:76 val : custom.js:76 val : 3 custom.js:76 val : , custom.js:76 val : custom.js:76 val : ' custom.js:76 val : p custom.js:76 val : r custom.js:76 val : o custom.js:76 val : d custom.js:76 val : u custom.js:76 val : c custom.js:76 val : t custom.js:76 val : _ custom.js:76 val : s custom.js:76 val : i custom.js:76 val : z custom.js:76 val : e custom.js:76 val : ' custom.js:76 val : : custom.js:76 val : custom.js:76 val : ' custom.js:76 val : M custom.js:76 val : e custom.js:76 val : d custom.js:76 val : i custom.js:76 val : u custom.js:76 val : m custom.js:76 val : custom.js:76 val : T custom.js:76 val : r custom.js:76 val : a custom.js:76 val : y custom.js:76 val : ' custom.js:76 val : , custom.js:76 val : custom.js:76 val : ' custom.js:76 val : p custom.js:76 val : r custom.js:76 val : o custom.js:76 val : d custom.js:76 val : u custom.js:76 val : c custom.js:76 val : t custom.js:76 val : _ custom.js:76 val : q custom.js:76 val : u custom.js:76 val : a custom.js:76 val : n custom.js:76 val : t custom.js:76 val : i custom.js:76 val : t custom.js:76 val : y custom.js:76 val : ' custom.js:76 val : : custom.js:76 val : custom.js:76 val : 2 custom.js:76 val : , custom.js:76 val : custom.js:76 val : ' custom.js:76 val : s custom.js:76 val : i custom.js:76 val : z custom.js:76 val : e custom.js:76 val : _ custom.js:76 val : d custom.js:76 val : e custom.js:76 val : s custom.js:76 val : c custom.js:76 val : r custom.js:76 val : i custom.js:76 val : p custom.js:76 val : t custom.js:76 val : i custom.js:76 val : o custom.js:76 val : n custom.js:76 val : ' custom.js:76 val : : custom.js:76 val : custom.js:76 val : ' custom.js:76 val : M custom.js:76 val : e custom.js:76 val : d custom.js:76 val : i custom.js:76 val : u custom.js:76 val : m custom.js:76 val : custom.js:76 val : T custom.js:76 val : r custom.js:76 val : a custom.js:76 val : y custom.js:76 val : custom.js:76 val : u custom.js:76 val : s custom.js:76 val : u custom.js:76 val : a custom.js:76 val : l custom.js:76 val : y custom.js:76 val : custom.js:76 val : e custom.js:76 val : n custom.js:76 val : o custom.js:76 val : u custom.js:76 val : g custom.js:76 val : h custom.js:76 val : custom.js:76 val : f custom.js:76 val : o custom.js:76 val : r custom.js:76 val : custom.js:76 val : 3 custom.js:76 val : custom.js:76 val : p custom.js:76 val : e custom.js:76 val : o custom.js:76 val : p custom.js:76 val : l custom.js:76 val : e custom.js:76 val : ' custom.js:76 val : , custom.js:76 val : custom.js:76 val : ' custom.js:76 val : s custom.js:76 val : i custom.js:76 val : z custom.js:76 val : e custom.js:76 val : _ custom.js:76 val : i custom.js:76 val : m custom.js:76 val : a custom.js:76 val : g custom.js:76 val : e custom.js:76 val : ' custom.js:76 val : : custom.js:76 val : custom.js:76 val : ' custom.js:76 val : t custom.js:76 val : r custom.js:76 val : a custom.js:76 val : y custom.js:76 val : . custom.js:76 val : j custom.js:76 val : p custom.js:76 val : g custom.js:76 val : ' custom.js:76 val : } :8000/static/images/undefined:1 GET http://localhost:8000/static/images/undefined 404 (NOT FOUND)
解决方案
方法1:将字典转为JSON字符串传递
Jinja直接输出的字典是Python格式的字符串,JS无法识别为对象,需要用tojson过滤器转为标准JSON格式:
- 修改模板中的
<option>标签:
<option value="{{ sizevalue|tojson }}">{{ sizevalue.product_size }}</option>
- 修改JavaScript函数,解析JSON字符串为对象:
function displayTryImg(size){ var resultStr = size.value; var result = JSON.parse(resultStr); console.log('result', result); document.getElementById("tray-img").src = "/static/images/" + result.size_image; }
方法2:提前渲染全局JS对象(更推荐)
避免在<option>的value中传递大量数据,先把所有尺寸数据转为JSON对象存到全局变量,下拉框只传尺寸ID:
- 在模板中添加全局变量:
<script> const productSizes = {{ product.sizes|tojson }}; </script>
- 修改
<option>标签的value为尺寸ID:
<option value="{{ sizekey }}">{{ sizevalue.product_size }}</option>
- 修改JavaScript函数,通过ID获取对应尺寸数据:
function displayTryImg(size){ var sizeId = size.value; var selectedSize = productSizes[sizeId]; document.getElementById("tray-img").src = "/static/images/" + selectedSize.size_image; }
这两种方法都能解决JS无法识别字典的问题,方法2更符合前端最佳实践,避免了在DOM属性中存储复杂数据。
内容的提问来源于stack exchange,提问作者Sajjad
相关产品推荐
相关产品推荐

