【问题标题】:Flask - use javascript to display loading page while waiting for task to complete [duplicate]Flask - 在等待任务完成时使用javascript显示加载页面[重复]
【发布时间】:2018-02-01 00:45:54
【问题描述】:

menu.html 中,单击给定链接会以这种方式呈现所选页面pasta.html

    <ul>
      <li><a href="{{ url_for('pasta') }}";>Pasta</a>
            <form action="{{ url_for('handle_menu') }}" method="post">
            <input type="radio" name="additive" value="Cheese"> <label style="font-size: 11px;">Cheese</label>
            </form>
      </li> 

但是假设@app.route('/pasta') 必须在“完成”之前“烹饪”一些“配料”:

 @app.route('/pasta')
 def pasta():

     # (perform some long task here)

     return render_template('pasta.html')

就此而言,我想在页面加载时显示/cooking 视图,如下所示:

@app.route('/cooking')
def cooking():
    return render_template('cooking.html')

如果我没记错的话,使用 Flaskjinja2 模板,您可以返回 (200) 或重定向 (301) 页面,对于像 loading.html 这样的任何中间页面,您需要 @ 987654333@.


那么,我如何在此处使用javascript 以显示cooking.html 页面同时 等待/pasta 任务完成,并且一旦任务完成,终于退货了?

【问题讨论】:

    标签: javascript jquery flask jinja2


    【解决方案1】:

    由于您使用的是 GET 请求,因此您可以将锚标记路由到 cooking,渲染 cooking.html 模板,然后使用 window.location.replace() 重定向到 pastapasta() 中的长任务将在 pasta.html 渲染之前执行。

    menu.html:

    <a href="{{ url_for('cooking') }}">Pasta</a>
    

    cooking.html:

    <script> window.location.replace('/pasta'); </script>
    

    对于 POST 请求,您需要将表单值发送到 cooking,将它们传递给模板,然后使用 AJAX 再次将它们发送到 pasta,最后在回调函数中重定向。

    menu.html:

    <form action="{{ url_for('cooking') }}" method='POST'>
    

    cooking():

    @app.route('/cooking')
    def cooking():
        return render_template('cooking.html', form_data=request.form['form_data'])
    

    pasta():

    @app.route('/pasta', methods=['GET', 'POST'])
    def pasta():
        if request.method == 'GET':
            render_template('pasta.html')
    
        # (perform some long task here)
    
        return make_response('POST request successful', 200)
    

    cooking.html:

    <script>
        $.ajax({
            type: 'POST',
            url: '/pasta',
            data: {
                form_data: '{{form_data}}',
            },
            success: function() {
                window.location.replace('/pasta');
            }
          });
    </script>
    

    【讨论】:

      【解决方案2】:

      您需要创建名为 cooking_request 的第三个端点:

      1. /cooking_request
      2. /cooking
      3. /pasta

      渲染/cooking_request 页面并在其中使用javascript 以使用Ajax 调用/cooking 页面。当/cooking 响应时,您将请求/pasta 内容并显示给用户。

      这是您可以在/cooking_request 页面中使用的示例代码。它将调用/cooking 页面,等待它,最后在 div#pasta-results 元素中呈现/pasta

      <div id="pasta-results">Please wait, loading...</div>
      
      <script type="text-javascript">
          function loadPasta() {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
              if (this.readyState == 4 && this.status == 200) {
                document.getElementById("pasta-results").innerHTML = this.responseText;
              }
            };
            xhttp.open("GET", "http://website-host/pasta", true);
            xhttp.send();
          }
      
          function loadCooking() {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
              if (this.readyState == 4 && this.status == 200) {
                loadPasta();
              }
            };
            xhttp.open("GET", "http://website-host/cooking", true);
            xhttp.send();
          }
      
          loadCooking();
      <script>
      

      【讨论】:

      • /pasta 仅在任务完成后才呈现...我不必等待吗?我想要在渲染之前执行任务时的解决方案。
      • 我在回复中编辑了示例以首先加载/cooking,然后是/pasta。由于您的/cooking 需要时间(如您所说),您的用户将不得不在某个时候等待它。除非您提高代码性能以使其更快。但是您的问题是关于如何从 Javascript 动态加载内容。我就是这么回答的……
      • 好的,但是第一次渲染 (/cooking_request) 发生在哪里?行动在哪里?我开始点击链接&lt;a href="{{ url_for('pasta') }}。我得把它改成{{ url_for('cooking_request) }}?
      • 正确。您可以随意命名每个端点。它只是简单地向您展示如何使用 JavaScript 加载内容并在用户界面上显示。
      猜你喜欢
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多