【问题标题】:Flask url_for URLs in Javascript烧瓶 url_for Javascript 中的 URL
【发布时间】:2012-05-06 02:04:48
【问题描述】:

在使用烧瓶时,在 Javascript 文件中创建动态 URL 的推荐方法是什么?在 jinja2 模板和 python 视图中使用url_for,在.js 文件中推荐的方法是什么?因为它们不被模板引擎解释。

基本上想做的是:

// in comments.js
$.post(url_for('comment.comment_reply'));

这是不可能的。

当然,我可以在模板中执行它:

<script>
    $.post(url_for('comment.comment_reply'));
</script>

【问题讨论】:

    标签: javascript python flask url-for


    【解决方案1】:

    @dumbmatter 的建议几乎被认为是事实上的标准方式。但我认为会有更好的方法来做到这一点。所以我设法开发了这个插件:Flask-JSGlue.

    添加{{ JSGlue.include() }}后,您可以在您的源代码中进行如下操作:

    <script>
        $.post(Flask.url_for('comment.comment_reply', {article_id: 3}));
    </script>
    

    或:

    <script>
        location.href = Flask.url_for('index', {});
    </script>
    

    【讨论】:

    • 这是一个非常好的解决方案。我无法更改脚本文件路径,在我的情况下是d3.json("{{url_for('static', filename='userdata/0af968589866013dbe09f57d3c78cc094666ff49.json')}}", ,因为文件路径信息在{{ url_for }} 命令中,所以我无法中断。但是,现在我可以将 var usermusics 定义为 0afblahblah.json 并像 Flask.url_for("static", {"filename": usermusics}) 一样使用它
    • 装饰器听起来是个好主意。但公平地说,没有暴露的端点并不能保证它的安全。除了不暴露端点之外,您还必须具有某种身份验证/安全性。我会将其添加到路线图中,我认为这是一种有效/更安全的方法。感谢您的意见,@Collin。
    • @Collin 在安全方面,您通常假设您的攻击者知道您的系统如何工作(请注意,“您的系统如何工作”确实不包括秘密密码、密钥等)。即使攻击者知道端点,您的系统也应该是安全的。还有其他获得它们的方法,例如社会工程,感染合法用户的机器,我相信这个名单还在继续。依靠不知道端点的攻击者是一种“通过默默无闻的安全”的形式,在实践中,这种技术通常不能很好地抵御真正的攻击者。
    • @Collin 另外请记住,您的网址基本上是公共信息。您的许多用户都认识他们,因此无论如何他们都难以保护。而且你实际上只是暴露了一个模式,所以攻击者仍然需要模式的输入。我认为这种少量的信息暴露不会大大增加您的风险。
    • @Collin 这就是你去找你的经理/客户说,“这个应用程序现在存在根本的安全漏洞,如果你重视自己的声誉,应该立即解决。这就是我的建议...”
    【解决方案2】:

    Flask documentation 建议在您的 HTML 文件中使用 url_for 来设置一个包含您可以在其他地方访问的根 URL 的变量。然后,您必须在此基础上手动构建视图 URL,尽管我猜您可以将它们存储为类似于根 URL。

    【讨论】:

    • 不是很漂亮,但我想它必须这样做!
    • 现在我再想一想,难道不能写一个 Flask 扩展来查看 Python 代码中定义的 URL 路由并动态地将其(无论何时发生变化)转换为等效的 JavaScript 代码,从而在 JavaScript 中提供等效的 url_for
    • 在答案中添加更多细节会有所帮助。我正在按照链接的建议进行操作,但是模板变量 request.script_root|tojson|safe 为我呈现为空字符串。不幸的是,文档链接没有给出一个独立的例子,我无法弄清楚它隐含的假设......
    • 是的,除此之外,如果您需要一个专门用于 Javascript 并且不适合 HTML 模板的 url_for,那么您可能应该编写一个小型 JS 库来执行您的 AJAX 请求.这个库可以从 Jinja2 动态创建的 JSON 中读取 url
    【解决方案3】:

    正在寻找解决方案,他们想出了这个解决方案

    • 无需插件

    • 无硬编码网址

    关键是要实现Jinja2 能够开箱即用地呈现javascript。


    将您的模板文件夹设置为如下所示:

    /template
        /html
            /index.html
        /js
            /index.js
    

    在你的意见中.py

    @app.route("/index_js")
    def index_js():
        render_template("/js/index.js")
    

    现在,而不是从您的静态文件夹中提供 javascript。你会使用:

    <script src="{{ url_for('index_js') }}"></script>
    

    毕竟,您是动态生成 javascript,它不再是静态文件。


    现在,在您的 javascript 文件中,只需像在任何 html 文件中一样使用 url_for

    例如使用Jquery 发出Ajax 请求

    $.ajax({
      url: {{ url_for('endpoint_to_resource') }},
      method: "GET",
      success: call_back()
    })
    

    【讨论】:

    • 我实际使用过这个解决方案,但重要的是要注意使用 jinja2 渲染所有 javascript 文件的性能影响,以及它对缓存的潜在影响。
    • 感谢您提供替代解决方案。请注意,您的视图功能中有错字。它应该是return render_template("/js/index.js") 而不是render_template("/js/index.js")
    【解决方案4】:

    @jeremy 的答案是正确的,可能是更常见的方法,但作为替代答案,请注意 dantezhu 编写并发布了一个 flask extension 声称执行建议的确切 url-route-map-to-javascript 翻译在评论中。

    【讨论】:

      【解决方案5】:

      我用了这个又脏又丑的把戏:

      "{{url_for('mypage', name=metadata.name,scale=93,group=2)}}"
      .replace('93/group',scale+'/group')
      

      scale 是我想用于 AJAX 请求的 javascript 变量。 因此, url_for 生成一个 URL 并且 JavaScript 在运行时替换该参数。生成的代码类似于:

      "/ajaxservive/mynam/scale/93/group/2".replace('93/group',scale+'/group')
      

      这很奇怪,但仍然找不到更优雅的解决方案。

      事实上,链接烧瓶扩展的looking at the code,它做同样的事情,但管理一般情况。

      【讨论】:

        【解决方案6】:

        就我而言, 我试图动态创建网址

        我按如下方式解决了我的问题(注意:我已将 Angular 的语法换成 {[x]}:

        <ul>
            <li ng-repeat="x in projects">
                {[x.title]}
                {% set url = url_for('static',filename="img/") %}
        
                <img src="{{url}}{[x.img]}">
            </li>
        </ul>
        

        【讨论】:

          【解决方案7】:

          通过在 Jinja2 和 Flask 中使用“tojson”,我能够将动态创建的 url 路由传递给 javascript 函数。

          要将动态 url 从 html 模板传递给 js,只需在 jinja 语句的末尾添加“|tojson”即可将其转换为适当的格式。

          代替:

          <script>
           $.post(url_for('comment.comment_reply'));
          </script>
          

          试试:

          <script>
           var route = {{ url_for('comment.comment_reply')|tojson }};
           yourJavaScriptFunction(route);
          </script>
          

          然后你就可以在你的js函数中使用路由作为你需要的正确路由。

          yourJavaScriptFunction(route){
           console.log(route);
          }
          

          【讨论】:

            【解决方案8】:

            按下按钮时,我试图调用 FLASK 路由。它应该收集响应并更新一个 div。该页面不应重新加载。

            我使用 jquery 来做到这一点。

            代码如下:

            @app.route('/<name>')
            def getContent(name):
                return 'This is %s' % name
            

            HTML:

                <div id="mySpace" class="my-3">Count</div>
            
                <button id="next_id" class="btn btn-primary">Press</button>
            
                <script>
                    $('#next_id').click(function (){
                        $.get('/aroy', function(data, status){
                        $('#mySpace').html(data);
                    });
                    });
                </script>
            

            【讨论】:

              【解决方案9】:

              我建议这样做:

              <script src="{{ url_for('static', filename='js/jquery.js') }}" type="text/javascript">
              </script>
              

              适合我

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-03-01
                • 1970-01-01
                • 2013-01-26
                • 1970-01-01
                • 2022-07-09
                相关资源
                最近更新 更多