在Python Flask应用程序上执行多个AJAX请求时出现Chrome浏览器错误



我当前正在使用命令"python3-m烧瓶run-h localhost-p 8081";在localhost:8081上运行flask服务器。用户可以点击按钮来触发事件;此外,数据更新被动态推送到javascript间隔触发的绘图图中。

当两个异步AJAX请求同时运行时,google Chrome上会出现问题-->

页面上有一些控件(如启动按钮(用于处理其他操作。当运行mozilla firefox时,这两个请求都将毫无问题地执行。然而,当使用谷歌Chrome时,点击按钮的请求会在几秒钟后开始挂起,需要更长的时间才能到达"完成请求";函数,直到最终导致页面崩溃。在下面的代码中,我写了一些控制台日志,在浏览器控制台中显示按钮单击事件停止回复";随机字符串";在运行几秒钟后从python路由。这似乎是chrome特有的问题,因为它在firefox上始终有效。

请告知-我如何更改它以可靠地跨两个浏览器工作?

代码

以下是javascript jquery AJAX请求:

var numerical_count_rate = document.getElementById("totalCounts");
var numerical_error_rate = document.getElementById("errorRate");
var start_btn = document.getElementById("startButtonClick");
var start_btn_clicked = function (){
console.log("button clicked...")
req = $.ajax({
url : "/_start_button_clicked",
type : "POST",
});
console.log("button got this far...")
req.done(function(data){
console.log("button got even further !!")
var data_test = JSON.parse(data)
var update = data_test.random_string
console.log(update)
});
};
var updateInterval = setInterval(update_values, 1000);
var counts = 0;
console.log("update_interval fired..")
function update_values(){
req = $.ajax({
url : "/_extend_plot",
type : "POST",
});
req.done(function(data){
var updates = JSON.parse(data);
var count_rate_update = {x: [[updates.x_count_rate]],y: [[updates.y_count_rate]]};
var error_rate_update = {x: [[updates.x_error_rate]],y: [[updates.y_error_rate]]};
Plotly.extendTraces('plotly_countrate',count_rate_update, [0], 50);
Plotly.extendTraces('plotly_errorrate',error_rate_update, [0], 50);
numerical_count_rate.innerHTML = "Total Count Rate: " + updates.y_count_rate.toString().replace(/(d)(?=(d{3})+(?!d))/g, '$1,');
numerical_error_rate.innerHTML = "Error Rate: " + parseFloat(updates.y_error_rate).toFixed(3).toString() + "%";
});
window.onresize = function() {
Plotly.Plots.resize( 'plotly_countrate' );
Plotly.Plots.resize( 'plotly_errorrate' )
};
counts++;
console.log(counts)
}

以下是来自主线程的片段-->ajax请求引用的Flask路由在主app.py文件中:

from flask import Flask, render_template,  request
import queue
import threading
import plotly
import json
import pandas as pd
import numpy as np
import random
import datetime

app = Flask(__name__)

@app.route("/", methods=['GET'])
def index():
initial_graphs_json = create_plots()
return render_template("index.html", count_rate_plot=initial_graphs_json[0], error_rate_plot=initial_graphs_json[1])

@app.route("/_extend_plot", methods=['GET', 'POST'])
def push_update():
timestamp = get_datetime()
updated_data = queue_q.get()
with queue_q.mutex:
queue_q.queue.clear()
client_post_updates = dict(
x_count_rate=timestamp,
x_error_rate=timestamp,
y_count_rate=updated_data["val0"] + updated_data["val1"],
y_error_rate=updated_data["val2"])
updatesJSON = json.dumps(client_post_updates, cls=plotly.utils.PlotlyJSONEncoder)
return updatesJSON

@app.route("/_start_button_clicked", methods=['GET', 'POST'])
def startstop_clicked():
update_dict = dict(
random_string="randomstring"
)
print("Python click method triggered...")
update = json.dumps(update_dict)
return update

if __name__ == "__main__":
app.run(host="0.0.0.0", port="8081", debug=True)

运行-python版本3.7,jquery版本3.5.1

更新:已解决

通过将函数转换为异步调用并将短轮询改为长轮询来解决问题。chrome似乎已经内置了将请求留在"中的功能;"未决状态";,短的轮询间隔使浏览器队列中充满了新的请求,这导致了停滞。目前还不完全清楚为什么在firefox上不会发生这种情况,但基于互斥锁和服务器端线程之间的公共内存控制下的单个定时器的长轮询是更好的总体实践。通过这种方式,推送更新的频率仅由可用数据控制,而不是由计时器轮询。

新JS代码:

var start_btn_clicked = async function (){
req = $.ajax({
url : "/_start_button_clicked",
type : "POST",
});
req.done(async function(data){
var data_test = JSON.parse(data);
var update = data_test.random_string;
});
};
update_values();
async function update_values(){
req = $.ajax({
url : "/_extend_plot",
type : "POST",
async: true,
cache: false,
timeout: 30000,
success: async function(data){
console.log(req);
var updates = JSON.parse(data);
var count_rate_update = {x: [[updates.x_count_rate]],y: [[updates.y_count_rate]]};
var error_rate_update = {x: [[updates.x_error_rate]],y: [[updates.y_error_rate]]};
Plotly.extendTraces('plotly_countrate',count_rate_update, [0], 50);
Plotly.extendTraces('plotly_errorrate',error_rate_update, [0], 50);
numerical_count_rate.innerHTML = "Total Count Rate: " + updates.y_count_rate.toString().replace(/(d)(?=(d{3})+(?!d))/g, '$1,');
numerical_error_rate.innerHTML = "Error Rate: " + parseFloat(updates.y_error_rate).toFixed(3).toString() + "%";
setTimeout(update_values, 1000);
},
});
window.onresize = async function() {
Plotly.Plots.resize( 'plotly_countrate' );
Plotly.Plots.resize( 'plotly_errorrate' );
};
}

最新更新