簡體   English   中英

Flask url_for 在模板的外部不起作用 JavaScript

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM