繁体   English   中英

页面刷新后,Ajax POST to Flask无法正常工作

[英]Ajax POST to Flask not working after page refresh

我正在改进用于远程控制望远镜的系统。 Raspberry Pi运行烧瓶,并为连接到望远镜的相机提供视频流。 望远镜的聚焦器由Arduino控制的步进电机驱动。服务器提供一个网站来显示视频流,并提供两个按钮来移动聚焦器。

单击任一按钮时,客户端将POST发送到RasPi,然后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 ''

网页(stream.html):

<html>
    <head>
        <title>Video Streaming</title>
        <style>
            ...
        </style>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

        <script>
                $(document).ready(function() {});
        </script>
      </head>

    <body>
        <h1>Streaming camera {{ wcam }}</h1>
        <br>
        <img id="bg" src="{{ url_for('video_feed', wcam=wcam) }}", height="480" width="640">
        <a href="{{ url_for('index') }}">Back</a>
        <br>


    <!--######################################################-->
    <!--#  Focuser handling -->
    <!--######################################################-->

    <br>
    <form id="flaskform" method="POST">
        <p>
        {{ form.nsteps.label }} {{ form.nsteps() }} &nbsp;
        {{ form.focuser_in() }} &nbsp;
        {{ form.focuser_out() }}
        </p>
    </form>

    <script>
    // $(document).ready(function() { // Moved to header

            var form = document.getElementById('flaskform');
            function onSubmit(event) {
                console.log('onSubmit function');
                var objectID = event.explicitOriginalTarget.id;
                var nsteps = form.nsteps.value;
                var return_data = {caller: "", steps: nsteps};
                if (objectID == "focuser_in") {
                    return_data.caller = objectID;
                    console.log("Focuser_in detected");
                } else if (objectID == "focuser_out") {
                    return_data.caller = objectID;
                    console.log("Focuser_out detected");
                } else if (objectID == "nsteps") {
                    console.log("nsteps detected");
                    event.preventDefault();
                    return;
                } else {
                    console.log("No matches");
                    return;
                }
                console.log("About to run Ajax");
                $.ajax({
                    url: "stream.html",
                    type: "post",
                    data: return_data,
                    success: function(response) {
                        console.log('It worked!');
                    },
                    error: function(xhr, status, text) {
                        console.log('An error occurred:', status,"; ", text);

                    },
                    timeout: 1000 // 1s
                }); // Ajax
                console.log("After running Ajax");
                if (event) { event.preventDefault(); }

            }
            // prevent when a submit button is clicked
            form.addEventListener('submit', onSubmit, false);

            //<!--form.addEventListener('submit', onSubmit, false);-->
            // prevent submit() calls by overwriting the method
            form.submit = onSubmit;

    //});  // Moved to header
    </script>
    </body>
</html>

问题如下:

如果我在客户端的浏览器上刷新页面,然后单击一个按钮,则ajax会执行POST,但flask似乎无法接收到它。 请求超时。

如果现在重新启动服务器(我正在使用PyCharm开发此服务器,那么我只需单击“重新运行”)而无需刷新客户端中的页面,然后单击一个按钮,flask确实获得了POST,并且聚焦器的工作原理像一个超级按钮。

如果再次刷新页面,则按钮将停止工作,直到我重置服务器。

为什么会这样? 显然,代码的主要目的是起作用的,但是页面刷新在某种程度上破坏了某些事情。

我曾经遇到过类似的问题,即摄像机线程阻止了所有呼叫。 当您重置服务器时,您的相机馈送是否仍在运行(在单击按钮之前)? 因为基本上您是两次调用相机供稿-刷新页面时首先使用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)

因此,基本上,您只保留流的get方法,并使用帖子进行移动。

感谢@Peter van der Wal向我指出解决方案。

视频流媒体有一个while True循环,该循环不断从摄像机获取帧,从而锁定线程。

解决的办法是 螺纹选项来启动应用程序:

之前:

app.run(host='0.0.0.0', debug=True)

现在:

app.run(host='0.0.0.0', debug=True, threaded=True)

这样,视频流线程就可以继续自己运行,同时允许服务器处理其他命令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM