Javascript HTML范围滑块到烧瓶,使用AJAX调用

Javascript HTML范围滑块到烧瓶,使用AJAX调用,javascript,python,ajax,flask,slider,Javascript,Python,Ajax,Flask,Slider,我有一个带有各种按钮和滑块的HTML控制面板。所有的按钮都是可操作的,当点击发送一个post请求时,我的Python应用程序接收并执行函数 我似乎无法使滑块控件正常工作,当我调整滑块时,出现以下错误: werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'but

我有一个带有各种按钮和滑块的HTML控制面板。所有的按钮都是可操作的,当点击发送一个post请求时,我的Python应用程序接收并执行函数

我似乎无法使滑块控件正常工作,当我调整滑块时,出现以下错误:

 werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'button'
这是有希望的,因为至少我可以看到它试图做一些事情却失败了,这是迄今为止取得的最好结果。我的javascript和AJAX知识是有限的,我需要一个解决方案,让滑块在python可以解释的任何onchange值上发布请求

我最初有以下HTML:

<input id="slider" type="range" min="0" max="100" value="50" onchange="updateVolume(getElementById('slider').value); return false;">
Python:

@main.route("/control_panel/<int:video_id>", methods=['GET', 'POST'])
def control_panel(video_id):
    video = video.query.get_or_404(video_id)

    if request.method == 'POST':

         ... #IF ELIF for various button functions here 

        volume = request.form['slider']
        return json.dumps({'volume': volume})

    return render_template('/control_panel.html', title=video.video, video=video)
HTML:


滑块
玩
出口
var slide=document.getElementById('slide'),
sliderDiv=document.getElementById(“sliderAmount”);
slide.onchange=函数(){
sliderDiv.innerHTML=this.value;
$.ajax({
url:“/index.html”,
数据:$('form')。序列化(),
键入:“POST”,
成功:功能(响应){
控制台日志(响应);
},
错误:函数(错误){
console.log(错误);
}
});
}
问题是因为
$('form')。serialize()
只从
发送值,而不是从
发送值,而是在您检查
请求的烧瓶中。form['button']
,它会引发错误,因为字典
请求.form
中不存在键
按钮

你必须使用

request.form.get('button')
当字典中不存在
按钮时,它返回
None


顺便说一句:

  • 您只有
    @app.route(“/”,…)
    ,因此AJAX必须发送到
    /
    ,而不是发送到
    /index.html

  • return…
    之后使用
    print(volume)
    是无用的,因为
    return
    结束函数

  • 在Flask中,您可以使用
    return jsonify(dict)
    而不是
    return json.dumps(dict)
    ,然后它发送特殊的头,JavaScript将其转换为对象,您可以获得
    response.volume
    。使用
    json.dumps(dict)
    将其作为html/文本发送,您必须使用
    json.parse(response).volume


在一个文件中工作代码(使用
template\u render\u string
而不是
template\u render
),因此每个人都可以轻松测试它

from flask import Flask, request, redirect, url_for, render_template, json, render_template_string, jsonify

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def control_panel():
    print('request.form:', request.form)
    
    if request.method == 'POST':
        if request.form.get('button') == 'button-play':
            print("play button pressed")

        elif request.form.get('button') == 'button-exit':
            print("exit button pressed")

        elif request.form.get('slide'):
            volume = request.form.get('slide')
            print('volume:', volume)
            #return jsonify({'volume': volume})
            return json.dumps({'volume': volume})

    print('render')
    return render_template_string('''<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <title>Slider</title>
  </head>
  <body>
    <div class="container" id="control_panel_1">
  <form action="/" method ="post" enctype="multipart/form-data" id="form">
    <div class="row">
            <div class="col">
              <button class="btn btn-primary" button type="submit" name="button" value="button-play">PLAY</button>

              <button class="btn btn-primary" button type="submit" name="button" value="button-exit">EXIT</button>

              <input id="slide" type="range" min="1" max="100" step="1" value="10" name="slide">
              <div id="sliderAmount"></div>
            </div>
    </div>
  </form>

    <!--- SCRIPTS --->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
<script>
  var slide = document.getElementById('slide'),
    sliderDiv = document.getElementById("sliderAmount");

slide.onchange = function() {
    sliderDiv.innerHTML = this.value;
    $.post({
            url: '/',
            data: $('form').serialize(),
            success: function(response){
                alert(response);
                alert(response.volume);             // works with jsonify()
                alert(JSON.parse(response).volume); // works with json.dumps()
                console.log(response);
            },
            error: function(error){
                alert(response);
                console.log(error);
            }
        });
}
</script>
</html>''')

if __name__ == '__main__':
    app.run(debug=True, use_reloader=False)
从flask导入flask、请求、重定向、url、呈现模板、json、呈现模板、字符串、jsonify
app=烧瓶(名称)
@app.route('/',方法=['GET','POST'])
def控制面板():
打印('request.form:',request.form)
如果request.method==“POST”:
如果request.form.get('button')=='button play':
打印(“按下播放按钮”)
elif request.form.get('button')=='button exit':
打印(“按下退出按钮”)
elif request.form.get('slide'):
volume=request.form.get('幻灯片')
打印('卷:',卷)
#返回jsonify({'volume':volume})
返回json.dumps({'volume':volume})
打印('呈现')
返回渲染模板字符串(“”)
滑块
玩
出口
var slide=document.getElementById('slide'),
sliderDiv=document.getElementById(“sliderAmount”);
slide.onchange=函数(){
sliderDiv.innerHTML=this.value;
美元邮政({
url:“/”,
数据:$('form')。序列化(),
成功:功能(响应){
警报(响应);
警报(response.volume);//与jsonify()一起使用
警报(JSON.parse(response.volume);//用于JSON.dumps()
控制台日志(响应);
},
错误:函数(错误){
警报(响应);
console.log(错误);
}
});
}
''')
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
运行(debug=True,use_reloader=False)

始终将完整的错误消息(从单词“Traceback”开始)作为文本(而不是屏幕截图)进行讨论(而不是评论)。还有其他有用的信息。错误显示某些
按钮有问题-您的代码中有按钮吗?它可以是变量按钮或参数按钮。为您的问题创建最小的工作代码,我们可以运行并查看问题。谢谢furas。我重新创建了问题的一个版本,希望我能获得一些见解。我会把它放在问题中。我运行了你的代码,它运行起来没有错误。它只给出了404,因为AJAX发送到
/index.html
,但是你没有
@app.route(“/index.html”)
,而是
@app.route(“/”)
,AJAX应该使用
/
而不是
/index.html
谢谢你提供了完整的演示,它可以完美地、轻松地集成到我的主代码中
@main.route("/control_panel/<int:video_id>", methods=['GET', 'POST'])
def control_panel(video_id):
    video = video.query.get_or_404(video_id)

    if request.method == 'POST':

         ... #IF ELIF for various button functions here 

        volume = request.form['slider']
        return json.dumps({'volume': volume})

    return render_template('/control_panel.html', title=video.video, video=video)
from flask import Flask, request, redirect, url_for, render_template, json

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def control_panel():
    if request.method == 'POST':
        if request.form['button'] == 'button-play':
            print("play button pressed")

        elif request.form['button'] == 'button-exit':
            print("exit button pressed")

        elif request.form['slider']:
            volume = request.form['slider']
            return json.dumps({'volume': volume})
            print(volume)

    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <title>Slider</title>
  </head>
  <body>
    <div class="container" id="control_panel_1">
  <form action="/" method ="post" enctype="multipart/form-data" id="form">
    <div class="row">
            <div class="col">
              <button class="btn btn-primary" button type="submit" name="button" value="button-play">PLAY</button>

              <button class="btn btn-primary" button type="submit" name="button" value="button-exit">EXIT</button>

              <input id="slide" type="range" min="1" max="100" step="1" value="10" name="slide">
              <div id="sliderAmount"></div>
            </div>
    </div>
  </form>

    <!--- SCRIPTS --->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
<script>
  var slide = document.getElementById('slide'),
    sliderDiv = document.getElementById("sliderAmount");

slide.onchange = function() {
    sliderDiv.innerHTML = this.value;
    $.ajax({
            url: '/index.html',
            data: $('form').serialize(),
            type: 'POST',
            success: function(response){
                console.log(response);
            },
            error: function(error){
                console.log(error);
            }
        });
}
</script>
</html>
request.form.get('button')
from flask import Flask, request, redirect, url_for, render_template, json, render_template_string, jsonify

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def control_panel():
    print('request.form:', request.form)
    
    if request.method == 'POST':
        if request.form.get('button') == 'button-play':
            print("play button pressed")

        elif request.form.get('button') == 'button-exit':
            print("exit button pressed")

        elif request.form.get('slide'):
            volume = request.form.get('slide')
            print('volume:', volume)
            #return jsonify({'volume': volume})
            return json.dumps({'volume': volume})

    print('render')
    return render_template_string('''<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <title>Slider</title>
  </head>
  <body>
    <div class="container" id="control_panel_1">
  <form action="/" method ="post" enctype="multipart/form-data" id="form">
    <div class="row">
            <div class="col">
              <button class="btn btn-primary" button type="submit" name="button" value="button-play">PLAY</button>

              <button class="btn btn-primary" button type="submit" name="button" value="button-exit">EXIT</button>

              <input id="slide" type="range" min="1" max="100" step="1" value="10" name="slide">
              <div id="sliderAmount"></div>
            </div>
    </div>
  </form>

    <!--- SCRIPTS --->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
<script>
  var slide = document.getElementById('slide'),
    sliderDiv = document.getElementById("sliderAmount");

slide.onchange = function() {
    sliderDiv.innerHTML = this.value;
    $.post({
            url: '/',
            data: $('form').serialize(),
            success: function(response){
                alert(response);
                alert(response.volume);             // works with jsonify()
                alert(JSON.parse(response).volume); // works with json.dumps()
                console.log(response);
            },
            error: function(error){
                alert(response);
                console.log(error);
            }
        });
}
</script>
</html>''')

if __name__ == '__main__':
    app.run(debug=True, use_reloader=False)