如何在独立.js文件中使用Python Flask?解决图片加载失败问题
这个问题我太熟悉了!核心原因其实很好理解:Flask的模板引擎只会渲染HTML模板文件,不会处理独立的.js文件。你写在script.js里的{{ url_for('static', filename='img/edit_w.svg') }}这类模板语法,根本不会被解析成实际的图片URL,浏览器会直接把它当作普通字符串去请求,自然找不到对应的图片资源。
下面给你几个实用的解决方案,按推荐程度排序:
方案1:在HTML中注入静态资源基础URL(最灵活)
我们可以先在HTML里让Flask解析出静态资源的基础路径,把它存在全局变量中,然后在JS文件里复用这个变量拼接图片路径:
步骤1:修改index.html,注入全局变量
在引入script.js之前,添加一段<script>标签,把静态资源的根路径存入全局变量:
<!-- 先注入静态资源基础路径,一定要放在引入script.js之前 --> <script> window.staticBaseUrl = "{{ url_for('static', filename='') }}"; </script> <!-- 再引入你的JS文件 --> <script type="text/javascript" src="{{ url_for('static', filename='js/script.js') }}"></script>
步骤2:修改script.js,使用全局变量拼接路径
把原来的模板语法替换成全局变量+图片相对路径:
function mouseOverSelf() { let img = document.getElementById("changeImg1"); let m = document.getElementById("changeColor1"); img.src = window.staticBaseUrl + "img/edit_w.svg"; m.style.color = "white"; } function mouseOutSelf() { let img = document.getElementById("changeImg1"); let m = document.getElementById("changeColor1"); img.src = window.staticBaseUrl + "img/edit.svg"; m.style.color = "black"; } function mouseOverExcel() { let img = document.getElementById("changeImg2"); let m = document.getElementById("changeColor2"); img.src = window.staticBaseUrl + "img/spreadsheet_w.svg"; m.style.color = "white"; } function mouseOutExcel() { let img = document.getElementById("changeImg2"); let m = document.getElementById("changeColor2"); img.src = window.staticBaseUrl + "img/spreadsheet.svg"; m.style.color = "black"; }
方案2:用HTML元素的data属性存储路径(更贴合语义)
我们可以把需要的图片路径提前通过模板引擎渲染到HTML元素的data-*属性里,然后JS直接读取这些属性:
步骤1:修改index.html,给图片添加data属性
给对应的img标签加上data-hover-src和data-default-src属性,用模板语法生成路径:
<img id="changeImg1" src="{{ url_for('static', filename='img/edit.svg') }}" data-hover-src="{{ url_for('static', filename='img/edit_w.svg') }}" data-default-src="{{ url_for('static', filename='img/edit.svg') }}" /> <span id="changeColor1">你的文本内容</span> <img id="changeImg2" src="{{ url_for('static', filename='img/spreadsheet.svg') }}" data-hover-src="{{ url_for('static', filename='img/spreadsheet_w.svg') }}" data-default-src="{{ url_for('static', filename='img/spreadsheet.svg') }}" /> <span id="changeColor2">你的文本内容</span>
步骤2:修改script.js,读取data属性
直接从元素的dataset对象里获取预渲染好的路径:
function mouseOverSelf() { let img = document.getElementById("changeImg1"); let m = document.getElementById("changeColor1"); img.src = img.dataset.hoverSrc; m.style.color = "white"; } function mouseOutSelf() { let img = document.getElementById("changeImg1"); let m = document.getElementById("changeColor1"); img.src = img.dataset.defaultSrc; m.style.color = "black"; } function mouseOverExcel() { let img = document.getElementById("changeImg2"); let m = document.getElementById("changeColor2"); img.src = img.dataset.hoverSrc; m.style.color = "white"; } function mouseOutExcel() { let img = document.getElementById("changeImg2"); let m = document.getElementById("changeColor2"); img.src = img.dataset.defaultSrc; m.style.color = "black"; }
方案3:直接使用相对路径(仅适用于路径固定的场景)
如果你的静态资源目录结构不会变动,也可以直接写相对路径。注意路径要根据script.js的位置调整:
比如script.js在/static/js/目录下,那么图片的相对路径是../img/xxx.svg(从js目录往上一级到static,再进入img目录):
function mouseOverSelf() { let img = document.getElementById("changeImg1"); let m = document.getElementById("changeColor1"); img.src = "../img/edit_w.svg"; m.style.color = "white"; } // 其他函数同理修改路径
这个方案的缺点是不够灵活,如果后续Flask的静态资源配置变更,所有路径都要手动修改,所以仅推荐在小型项目或路径固定的场景使用。
内容的提问来源于stack exchange,提问作者Suhyeon CHOI

