Javascript HTML范围滑块到烧瓶,使用AJAX调用
我有一个带有各种按钮和滑块的HTML控制面板。所有的按钮都是可操作的,当点击发送一个post请求时,我的Python应用程序接收并执行函数 我似乎无法使滑块控件正常工作,当我调整滑块时,出现以下错误: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
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)