Flask 动态数据更新,无需重新加载页面

Posted

技术标签:

【中文标题】Flask 动态数据更新,无需重新加载页面【英文标题】:Flask Dynamic data update without reload page 【发布时间】:2017-04-19 04:55:53 【问题描述】:

我正在尝试创建类似 Google Suggest Tool 的东西(通过建议 api http://suggestqueries.google.com/complete/search?output=toolbar&hl=ru&q=query)

我正在监听输入变化,并通过 GET 发送数据:

$("#search_form_input").keyup(function()
var some_var = $(this).val();
   $.ajax(
      url: "",
      type: "get", //send it through get method
      data:jsdata: some_var,
      success: function(response) 

      ,
      error: function(xhr) 
        //Do Something to handle error
      
    );

之后我正在处理这些数据并将其发送到 Google API 并在 Python 中得到响应:

@app.route('/', methods=['GET', 'POST'])
def start_page_data():
    query_for_suggest = request.args.get('jsdata')

    if query_for_suggest == None:
        suggestions_list = ['',]
        pass
    else:
        suggestions_list = []
        r = requests.get('http://suggestqueries.google.com/complete/search?output=toolbar&hl=ru&q=&gl=in'.format(query_for_suggest), 'lxml')
        soup = BeautifulSoup(r.content)
        suggestions = soup.find_all('suggestion')
        for suggestion in suggestions:
            suggestions_list.append(suggestion.attrs['data'])
        print(suggestions_list)
    return render_template('start_page.html', suggestions_list=suggestions_list)

在 Jinja 中试图以 HTML 动态打印它:

        <label id="value_lable">


            % for suggestion in suggestions_list %
                 suggestion 
            % endfor %

        </label>

但 Jinja 中的变量不会动态更新并打印空列表。

如何在 HTML 中动态打印列表中的建议?

【问题讨论】:

javascript 中,你的 success: 函数是空的,所以你对来自 Flask 的数据什么也不做。 我需要解决什么问题? 我想你不知道 AJAX/JavaScript 是如何工作的。 JavaScript 向 Flask 发送数据,Flask 发送回一些数据 - 比 JSON 更好 - JavaScript 接收这些数据并在浏览器中更新 HTML。 你能发几个例子,如何处理这个? success 函数你必须在 HTML 中找到元素 - 使用 $(...) - 然后你可以更新它 - 使用你在 response 中的数据。 【参考方案1】:

工作示例:

app.py

from flask import Flask, render_template, request
import requests
from bs4 import BeautifulSoup


app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/suggestions')
def suggestions():
    text = request.args.get('jsdata')

    suggestions_list = []

    if text:
        r = requests.get('http://suggestqueries.google.com/complete/search?output=toolbar&hl=ru&q=&gl=in'.format(text))

        soup = BeautifulSoup(r.content, 'lxml')

        suggestions = soup.find_all('suggestion')

        for suggestion in suggestions:
            suggestions_list.append(suggestion.attrs['data'])

        #print(suggestions_list)

    return render_template('suggestions.html', suggestions=suggestions_list)


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

index.html

<!DOCTYPE html>

<html>

<head>
    <title>Suggestions</title>
</head>

<body>

Search: <input type="text" id="search_form_input"></input>

<div id="place_for_suggestions"></div>

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

<script>
$("#search_form_input").keyup(function()
    var text = $(this).val();

    $.ajax(
      url: "/suggestions",
      type: "get",
      data: jsdata: text,
      success: function(response) 
        $("#place_for_suggestions").html(response);
      ,
      error: function(xhr) 
        //Do Something to handle error
      
    );
);
</script>

</body>

</html>

suggestions.html

<label id="value_lable">
    % for suggestion in suggestions %
         suggestion <br>
    % endfor %
</label>

【讨论】:

这被认为是安全的吗?有人可以导航到 https://.../suggestions,它会返回一个页面。除非调用来自 AJAX 请求,否则有什么方法可以防止返回呈现的模板? 您可以检查if request.is_xhr: 以查看它是否是AJAX - 但有人可以使用其他工具(即Python 模块requests)发送带有标题X-Requested-With: XMLHttpRequestis_xhr 的请求将返回True。您可以检查其他标题 - 即。 User-Agent - 识别它是否是浏览器,但其他工具也可以发送正确的标题User-Agent。问题是你是否真的需要这么“安全”的版本。

以上是关于Flask 动态数据更新,无需重新加载页面的主要内容,如果未能解决你的问题,请参考以下文章

Ajax是什么?

Ajax动态网页技术:局部更新部分网页的原理与过程(附代码)

ajax

node.js + mysql + ejs 数据插入后无需重新加载页面即可更新屏幕信息

AJAX

多种动态形式,e.preventDefault();未正确触发