Javascript 页面刷新后Ajax发送到烧瓶不工作

Javascript 页面刷新后Ajax发送到烧瓶不工作,javascript,python,jquery,ajax,flask,Javascript,Python,Jquery,Ajax,Flask,我正在改进一个远程控制望远镜的系统。树莓圆周率运行烧瓶,并提供了一个摄像头连接到望远镜视频流。望远镜的调焦器由步进电机驱动,步进电机由Arduino控制。服务器提供一个显示视频流的网站,并提供两个按钮将调焦器移入和移出 当点击任一按钮时,客户机向RasPi发送POST,然后RasPi通知Arduino移动焦点。但至关重要的是,我不想在重新聚焦时刷新页面。因此,我使用jQuery和Ajax来抑制页面刷新 相关代码片段如下所示: Python/Flask代码: @app.route('/stream

我正在改进一个远程控制望远镜的系统。树莓圆周率运行烧瓶,并提供了一个摄像头连接到望远镜视频流。望远镜的调焦器由步进电机驱动,步进电机由Arduino控制。服务器提供一个显示视频流的网站,并提供两个按钮将调焦器移入和移出

当点击任一按钮时,客户机向RasPi发送POST,然后RasPi通知Arduino移动焦点。但至关重要的是,我不想在重新聚焦时刷新页面。因此,我使用jQuery和Ajax来抑制页面刷新

相关代码片段如下所示:

Python/Flask代码:

@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)