Javascript 页面刷新后Ajax发送到烧瓶不工作
我正在改进一个远程控制望远镜的系统。树莓圆周率运行烧瓶,并提供了一个摄像头连接到望远镜视频流。望远镜的调焦器由步进电机驱动,步进电机由Arduino控制。服务器提供一个显示视频流的网站,并提供两个按钮将调焦器移入和移出 当点击任一按钮时,客户机向RasPi发送POST,然后RasPi通知Arduino移动焦点。但至关重要的是,我不想在重新聚焦时刷新页面。因此,我使用jQuery和Ajax来抑制页面刷新 相关代码片段如下所示: Python/Flask代码:Javascript 页面刷新后Ajax发送到烧瓶不工作,javascript,python,jquery,ajax,flask,Javascript,Python,Jquery,Ajax,Flask,我正在改进一个远程控制望远镜的系统。树莓圆周率运行烧瓶,并提供了一个摄像头连接到望远镜视频流。望远镜的调焦器由步进电机驱动,步进电机由Arduino控制。服务器提供一个显示视频流的网站,并提供两个按钮将调焦器移入和移出 当点击任一按钮时,客户机向RasPi发送POST,然后RasPi通知Arduino移动焦点。但至关重要的是,我不想在重新聚焦时刷新页面。因此,我使用jQuery和Ajax来抑制页面刷新 相关代码片段如下所示: Python/Flask代码: @app.route('/stream
@app.route('/stream/<wcam>', methods=['GET'])
def stream_get(wcam):
class FocuserForm(FlaskForm):
nsteps = IntegerField('# steps: ', default=1)
focuser_in = SubmitField('Focuser in')
focuser_out = SubmitField('Focuser out')
form = FocuserForm()
return render_template('stream.html', wcam=wcam, form=form)
@app.route('/stream/<wcam>', methods=['POST'])
def stream_post(wcam):
results = request.form
arduino_serial = SerialFocuser()
if results['caller'] == "focuser_in":
command = "MVD" + results['steps'] + "\n"
arduino_serial.send_command(command)
elif results['caller'] == "focuser_out":
command = "MVU" + results['steps'] + "\n"
arduino_serial.send_command(command)
return ''
@app.route('/stream/',方法=['GET'])
def stream_get(wcam):
类FocuserForm(烧瓶形式):
nsteps=IntegerField(“#步骤:”,默认值=1)
调焦器_in=SubmitField('调焦器in')
调焦器输出=提交字段(“调焦器输出”)
form=FocuserForm()
返回呈现模板('stream.html',wcam=wcam,form=form)
@app.route('/stream/',methods=['POST'])
def流_柱(wcam):
结果=request.form
arduino_serial=SerialFocuser()
如果结果['caller']==“focuser_in”:
command=“MVD”+结果['steps']+“\n”
arduino_串行发送_命令(命令)
elif结果['caller']==“调焦器输出”:
command=“MVU”+结果['steps']+“\n”
arduino_串行发送_命令(命令)
返回“”
网页(stream.html):
视频流
...
$(文档).ready(函数(){});
流媒体摄像机{{wcam}}
{{form.nsteps.label}{{form.nsteps()}}
{{form.focuser_in()}}
{{form.focuser_out()}}
//$(文档).ready(函数(){//移动到页眉
var form=document.getElementById('flaskform');
提交函数(事件){
log('onSubmit函数');
var objectID=event.explicitOriginalTarget.id;
var nsteps=form.nsteps.value;
var return_data={caller:,步骤:nsteps};
if(objectID==“focuser_in”){
return_data.caller=objectID;
console.log(“检测到聚焦_”);
}else if(objectID==“聚焦输出”){
return_data.caller=objectID;
console.log(“检测到焦点_out”);
}else if(objectID==“nsteps”){
console.log(“检测到nsteps”);
event.preventDefault();
返回;
}否则{
console.log(“无匹配项”);
返回;
}
log(“即将运行Ajax”);
$.ajax({
url:“stream.html”,
类型:“post”,
数据:返回_数据,
成功:功能(响应){
log('It worked!');
},
错误:函数(xhr、状态、文本){
log('发生错误:',状态,;',文本);
},
超时:1000//1s
});//Ajax
log(“在运行Ajax之后”);
if(event){event.preventDefault();}
}
//单击提交按钮时阻止
表格.附录列表(“提交”,提交,虚假);
//
//通过覆盖方法防止submit()调用
form.submit=onSubmit;
//}); // 移到页眉
问题如下:
如果我在客户端浏览器上刷新页面,然后单击一个按钮,ajax会发布,但flask似乎没有收到。请求超时
如果我现在重新启动服务器(我正在用PyCharm开发它,所以我只需单击“重新运行”)而不刷新客户端中的页面,然后单击一个按钮,flask就会收到帖子,焦点用户就像一个魔咒一样工作
如果我再次刷新页面,则按钮将停止工作,直到我重置服务器
为什么会发生这种情况?显然,代码的主要用途是工作的,但不知怎么的,页面刷新破坏了某些东西。我曾经遇到过一个类似的问题,摄像头线程阻止了所有调用。重置服务器时,相机馈送是否仍在运行(单击按钮之前)? 因为基本上你是在两次调用你的相机提要——首先是在刷新页面时使用get调用,然后是post调用 为了清晰起见,我建议您将提交的代码重构为替代函数:
@app.route('/stream/<wcam>', methods=['POST'])
def moveCommand:
if form.is_submitted():
# POST method
results = request.form
arduino_serial = SerialFocuser()
if results['caller'] == "focuser_in":
command = "MVD" + results['steps'] + "\n"
arduino_serial.send_command(command)
elif results['caller'] == "focuser_out":
command = "MVU" + results['steps'] + "\n"
arduino_serial.send_command(command)
@app.route('/stream/',方法=['POST'])
def moveCommand:
如果表单已提交():
#POST方法
结果=request.form
arduino_serial=SerialFocuser()
如果结果['caller']==“focuser_in”:
command=“MVD”+结果['steps']+“\n”
arduino_串行发送_命令(命令)
elif结果['caller']==“调焦器输出”:
command=“MVU”+结果['steps']+“\n”
arduino_串行发送_命令(命令)
因此,基本上您只保留流媒体的get方法,并使用post进行移动。感谢@Peter van der Wal为我指出了解决方案 视频拖缆有一个
while True
循环,它不断地从摄像机获取帧,从而锁定线程
解决方案是通过以下选项启动应用程序:
之前:
app.run(host='0.0.0.0', debug=True)
现在:
这允许视频流线程自己继续,同时允许服务器处理其他命令。url:“stream.html”?你应该把URL放在这里,而不是html。嗨,彼得。是的
app.run(host='0.0.0.0', debug=True)
app.run(host='0.0.0.0', debug=True, threaded=True)