提问人:JBatswani 提问时间:8/2/2023 最后编辑:Abdulrahman HasanatoJBatswani 更新时间:8/3/2023 访问量:55
发布/获取请求不起作用(AJAX、Flask)
Post/Get request not working (AJAX, Flask)
问:
我正在尝试创建一个 YouTube 抓取器网页(用于教育目的;我永远不会发表它。只是想用它来学习)。我目前拥有的是一个网页,其中包含一个文本框,该文本框采用搜索查询和搜索按钮。当按下搜索按钮时,文本框的内容通过 Ajax post 请求(下面的代码)发送到 Python flask 文件,我使用一些库来搜索 youtube,然后 Python 文件将搜索结果链接打印到终端。我希望发生的事情是将搜索结果显示在我的网页上供用户阅读,但我一生都无法弄清楚如何让 Flask Python 文件将其结果发送到 HTML 页面。
index.html:
<body>
<center>
<span>
<img src="{{ url_for('static', filename='assets/logo.png') }}" style="float: left;" id="logo">
<input type="text" class="textbox" id="searchbar" style="width: 500px; height: 30px">
<button style="height: 30px" onclick="performPost()">Search</button>
</span>
</center>
</body>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script>
function performPost(){
$.ajax({
type: "POST",
url: "{{ url_for('search') }}",
data: {"search" : document.getElementById("searchbar").value},
})
}
</script>
main.py:
import urllib.request
import urllib.parse
import re
from flask import Flask, render_template, request
def searchSite(searchInput):
query_string = urllib.parse.urlencode({"search_query" : searchInput})
html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string)
search_results = re.findall(r'watch\?v=(.{11})', html_content.read().decode())
return (search_results)
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', text = "heehee")
@app.route('/index.html', methods=['POST', 'GET']) #NOTE: i just changed this line. It used to say @app.route('/', methods=['POST', 'GET'])
def search():
if request.method == 'POST':
data = request.form
searchQuery = data.getlist('search')[0]
searchResults = searchSite(searchQuery)
searchList = []
for i in range(10):
searchList.append("http://www.youtube.com/watch?v=" + str(searchResults[i]))
print(searchList)
return render_template('index.html', name = "jaaa")
if __name__ == '__main__':
app.run(
host = '127.0.0.1',
port = 5001,
debug = True
)
输出到终端:输出.png
答:
发送 AJAX 请求时,页面不会自动重新呈现。开发人员负责将相关数据插入到页面中。
以下示例演示如何在回调中向页面添加响应。
import urllib.request
import urllib.parse
import re
from flask import Flask, render_template, request
def searchSite(searchInput):
query_string = urllib.parse.urlencode({"search_query" : searchInput})
html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string)
search_results = re.findall(r'watch\?v=(.{11})', html_content.read().decode())
return (search_results)
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.post('/')
def search():
data = request.form
search_query = data.get('search')
search_results = searchSite(search_query)
search_list = []
for i in range(10):
search_list.append("http://www.youtube.com/watch?v=" + str(search_results[i]))
print(search_list)
return render_template('results.html', **locals())
HTML (./templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<center>
<span>
<img src="{{ url_for('static', filename='assets/logo.png') }}" style="float: left;" id="logo" />
<form onsubmit="handleSubmit(event)">
<input type="text" class="textbox" id="searchbar" style="width: 500px; height: 30px">
<button type="submit" style="height: 30px">Search</button>
</form>
</span>
<div id="results"></div>
</center>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script>
function handleSubmit(event) {
event.preventDefault();
$.ajax({
type: "POST",
url: "{{ url_for('index') }}",
data: { search : $('#searchbar').val() },
}).then(data => {
$('#results').html(data);
});
}
</script>
</body>
</html>
HTML (./templates/results.html)
{% for result in search_list -%}
<div>
<a href="{{ result }}">Result {{ loop.index }}</a>
</div>
{% endfor -%}
对服务器的传统请求会导致页面被完全重新加载和呈现。这需要时间,为用户阻止页面并使执行不那么流畅,但由浏览器自动完成。另一方面,AJAX 调用旨在在后台加载页面的各个部分,并使页面适应环境。在这种情况下,将数据输入到页面中。
您成功发送了请求,但忽略了服务器的响应。 等待服务器的响应,并将元素的内容替换为接收到的 HTML 数据的 id。
由于您只替换了页面的一部分,因此您不需要整个模板,只需要摘录,因此第二个模板。
如前所述,数据传输是一个异步过程,必须等待。为此,对 Promise
做出反应的块。这里提到的一种解决方案是,一旦任务完成,块中传递的函数就会被调用。另一种可能性是中断执行并使用 await
挂起所有后续命令,直到处理完成。但是,这需要将执行函数定义为异步
。then(data => { $('#results').html(data); }
results
results.html
then
then
评论
then(data => { $('#results').html(data); }
评论