[英]Flask url_for doesn't work in template's external JavaScript
在 index.html 中,我鏈接到一個 index.js 文件。 單擊一個按鈕,js 向 Flask 后端發送請求。 后端返回一個 static 文件路徑:'data/Sharon_4.png'。 我想使用以下 function 在 HTML 中渲染它,但它不起作用。 為了簡化它,我將 URL 替換為特定的 URL,如下所示,而不是變量。 它仍然不起作用。
function test(){
var mvt = document.getElementById('movieThumbnail')
var ig = document.createElement('img')
ig.src = `{{url_for('static', filename='data/haron_4.png')}}`
mvt.append(ig)
}
在 HTML 中,標簽似乎是正確的<img src="{{url_for('static', filename='data/Sharon_4.png')}}">
如果我將此標記直接放在 HTML 或頁內腳本中,它就可以工作。 但是這里在 js 中使用 url_for 卻不行。
Jinja2 模板處理器通常用於 Flask 應用程序,僅適用於模板文件。 您正在通過<script>
元素導入 JavaScript。 模板處理器不會看到 JavaScript。如果將 JavaScript 直接放入 HTML 文件中,它將由 Jinja2 處理。示例:
<script>
function test(){
var mvt = document.getElementById('movieThumbnail')
var ig = document.createElement('img')
ig.src = `{{url_for('static', filename='data/haron_4.png')}}`
mvt.append(ig)
}
</script>
你可以做的是使用這個簡單的腳本將 static 文件夾存儲在 window 變量中並在你的腳本中使用它。 例子:
<script>
window.static_folder = "{{url_for('static')}}";
</script>
然后在腳本中引用全局變量。 粗略的例子:
function test(){
const mvt = document.getElementById('movieThumbnail');
const ig = document.createElement('img');
ig.src = `${window.static_folder}/data/haron_4.png`;
mvt.append(ig);
}
或者,您可以在 Flask 服務器上調用 api 來獲取url_for
。 請看這個例子:
@bp.route('/url_for/')
def public_get_url_for():
"""
get the url using the url_for method. url parameters are given as request args
ie: /url_for?endpoint=stock_edit&stock_id=12
example:
$.get({
url: '/url_for',
data: {endpoint: 'stock_edit', stock_id: $('#stock_id').val()}
}).then(url => window.location = url);
for route:
@app.route('/stock_edit/<int:stock_id>')
def stock_edit(stock_id):
# some code
:return: the url or 404 if error
"""
keywords = request.args.to_dict()
try:
return url_for(**keywords)
except Exception as e:
return str(e), 404
我意識到這現在有點老問題了,但我在調查是否有“燒瓶”方法來做到這一點時遇到了這個問題,所以我想包括我是如何解決這個問題的。
如果像我一樣,您的 javascript 文件包含一堆 ajax api 調用,並且您不想在進行更改時冒破壞它們的風險,並且您也不希望每個模板文件或一個大塊的 javascript在布局模板中內聯 javascript,那么這可能對您有用:
為路徑“/js”創建一個路由,它將文件名作為參數,然后返回指定文件名的渲染。
from flask import Blueprint, abort, render_template
js = Blueprint('js', __name__, url_prefix='/js')
@js.route('/<filename>', methods=['GET'])
def file(filename):
# Prevent attempts to go outside of the js directory or return a different type of file
if "../" in filename or ".js" not in filename:
abort(404)
else:
# Go ahead and try to return the file, if it doesn't exist, return a 404
try:
return render_template("js/" + filename)
except:
abort(404)
app.register_blueprint(js.js)
然后在 flask 項目的模板目錄中創建一個名為“js”的文件夾,並將需要 jinja 的所有 javascript 文件移動到該目錄。
/ {root}
|____templates
|____layout.html
|____some_other_template.html
|____js
|____myJSFile.js
然后在您的模板中,您可以使用如下所示的腳本標簽:
<script src="{{ url_for('js.file', filename='myJSFile.js') }}" referrerpolicy="origin"></script>
此時,雖然它們出現在 html output 中以像普通腳本鏈接一樣加載,但它們實際上是作為 jinja 模板加載的,您可以在其中使用任何您喜歡的 jinja。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.