【问题标题】:Flask render_template() not being called after client POST with data客户端 POST 数据后未调用 Flask render_template()
【发布时间】:2021-04-19 15:12:16
【问题描述】:

我有一个带有 index.html 的烧瓶应用程序,它有一个运行进程的提交输入。我正在尝试捕获错误跟踪路由,然后导航到错误页面以在发生错误时从进程中显示该跟踪路由。但是在服务器上,我的render_template() 没有被调用。

index.html 具有提交输入,该输入通过重定向到 b.html 来运行进程,其中使用 Fetch api 的方法获取映射路径 /run,然后进程运行。该过程运行良好,但如果我插入错误进行测试,则会引发错误并将以下 JSON 对象发送到 b.html:

{'run_result':'run_failure' , 'error_output':output} 

如果返回码不为零,输出是来自 subprocess.run() 的 stdout=PIPE。

在 b.html 中,我有这个:

const nav = async() => {
    const response = await fetch('run');
    if( response.status !== 200 ) {
        throw new Error('error message');
    }
    return await response.json();
};

document.addEventListener('DOMContentLoaded', () => {
  nav().then(data => {
    if(data != null) {
      if(typeof(data) === 'object') {
        if(data['run_result'] === 'run_success'){       
            // ...successful run <== works fine!                                    
        } else {
          var error_output = data['error_output'];
          var sent_data = { 'data': error_output};
          fetch(`/run_error`, {                     // posts data to server uri
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(sent_data)
          })

          // ***I used to have '=> response.json()' here, but I got SyntaxError: "JSON.parse: unexpected character at line 1 column 1..." 
          .then(response => response)               

          // ***console only displays 'success:' here, not sent_data value
          .then(console.log('Success:', sent_data));    
        }
      }
    }
  });
});

在服务器上,我有:

# server output shows the below is called: 
#   127.0.0.1 - - [..date..] "POST /run_error HTTP/1.1" 200
@app.route('/run_error', methods=['POST'])  
    def error():
        if request.method = 'POST':
            request_json = request.json
            error_output = request_json['data']

            # perfectly prints out a str version of error trace
            print('***error:', error_output)    

            # run_error.hthml is **not** rendered with output - Why?
            return render_template('run_error.html', error_output=error_output)

        

为什么不调用 render_template()?

21 年 4 月 20 日回复

由于我在运行时遇到语法错误,我无法按照您在下面建议的操作。

.then(
    console.log('Success:', sent_data);
    var response = JSON.parse(response);
    var error_output = response["error_output"]; 
    window.location.href = "display_error/"+error_output;
); 

...但这是我现在的位置(注释掉的 then() 语句将正确的值打印到控制台):

document.addEventListener('DOMContentLoaded', () => {
  nav().then(data => {
    if(data != null) {
      if(typeof(data) === 'object') {
        if(data['run_result'] === 'run_success'){       
            // ...successful run <== works fine!                                    
        } else {
          var error_output = data['error_output'];
          var sent_data = { 'data': error_output};
          fetch(`/run_error`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(sent_data)
          })
          .then(response => response.text())    
          .then(response => JSON.parse(response))    
          //.then(response => console.log(response['error_output']))    
          .then(response => response['error_output'])    
          .then(response => {
            window.location.href = 'display_error/' + response;
          })    
        }
      }
    }
  });
});


@app.route('/run_error', methods=['POST'])  
def error():
    if request.method = 'POST':
        request_json = request.json
        error_output = request_json['data'] 
        return json.dumps({'error_output': error_ouput})

@app.route('/display_error/<error_output>', methods=['GET'])
def display_error(error_ouput):
    return render_template('run_error.html', error_output=error_output)

当它遇到错误时,我得到一个 404。 浏览器 URL 字段显示:

127.0.0.1:5000/display_error/Traceback....

^^^Traceback 没有引号。应该吗?

服务器控制台显示:

127.0.0.1 - - [date] "GET /display_error/Traceback...." 404

建议?

【问题讨论】:

    标签: javascript python flask fetch


    【解决方案1】:

    这是因为您在处理 POST 请求时返回了模板。您实际上是将模板解析为对客户端的响应,而不是作为要呈现的页面。相反,我建议您重定向到另一个视图函数以显示来自客户端的 GET 请求的错误,您将 error_output 作为查询字符串的值传递给该请求字符串。如果需要事先在输出上运行一些逻辑,可以保留原来的视图函数error。否则,您可以直接使用新的display_error,而无需通过第一个。

    @app.route('/run_error/', methods=['POST'])  
    def error():
        if request.method = 'POST':
            request_json = request.json
            error_output = request_json['data'] 
    
            return json.dumps({'error_output': error_ouput})
    
    @app.route('/display_error/', methods=['GET'])
    def display_error():
        error_output = request.args.get('error_output')
        return render_template('run_error.html', error_output=error_output)
    

    客户端将在成功发布请求(或没有它)后重定向到display_error 视图函数并将error_output 作为参数传递:

    .then(response => response)               
    .then(
        console.log('Success:', sent_data);
        var response = JSON.parse(response);
        var error_output = response["error_output"]; 
        window.location.href = "/display_error/?error_output="+error_output;
    ); 
    

    【讨论】:

    • 最后一部分的“状态”从何而来?
    • 你的成功(响应)片段可以在我的 .then(response => response) 中解析吗?
    • 抱歉,应该是error_output。只是更改了 sn-p,所以它可以在您的代码中使用。
    • 我接受了这个答案,尽管我们还没有完全解决它。我想我们已经接近了!
    • 终于(!)回到了这个问题,它成功了!!再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 2018-10-20
    • 2018-11-28
    • 2014-06-12
    相关资源
    最近更新 更多