如何使用 Javascript 呈现 Flask Web 应用 [复制]

How to render Flask Web App with Javascript [duplicate]

提问人:sgeza 提问时间:10/5/2018 最后编辑:sgeza 更新时间:10/8/2018 访问量:3969

问:

编辑:嗨,我已经检查了这个问题的重复项,他们没有询问SPA(客户端与服务器渲染)

我正在尝试将我的 Flask Web 应用程序更改为在 JS 中呈现客户端,而不是使用 Jinja 模板在服务器端呈现。一位面试官告诉我,我的 Flask Web App 的问题在于,应用服务器通常只应该提供纯 Json API,而不是尝试渲染任何现有的静态内容(例如不变的网站内容、主题、css、logo、图片等),因为这会浪费应用服务器的计算资源。

关于我的 Web 应用程序,它的作用是调用 2 个不同的 API,并根据用户输入(例如您的居住地)返回您的停车场空闲地段

我已经对将 AJAX 与 Flask 一起使用进行了一些研究。似乎基于 https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started 使用是要走的路。根据我有限的理解,如果实现得当,是否有可能将我的 Web 应用程序切换到基本上复制 SPA 功能的应用程序?(无页面刷新,客户端呈现)XMLHttpRequest

目前正在为实施而苦苦挣扎,任何帮助都会很棒!

下面的.py脚本

# one of Four routes in my "Main" Flask Script
@app.route('/address',methods = ['POST', 'GET'])
def address1():
    if request.method == 'POST':
        desired_CP_Address = request.form["address"]

        response = requests.get("https://data.gov.sg/api/action/datastore_search?resource_id=139a3035-e624-4f56-b63f-89ae28d4ae4c&q=" + desired_CP_Address)
        r = response.json()

        CP_Info = r['result']['records']
        return render_template("address1.html", text=CP_Info)

生成的 html 页面的代码段

<body>
<h1>carpark.py</h1>

<!-- if invalid input display bottom -->
{% if text %}   
    <h3>Click on your desired carpark number</h3>
<hr>

    {% for x in text %}
      <p>{{ x["address"] }} : <strong><a href="">{{ x["car_park_no"] }}</a></strong> </p>
    {% endfor %}
JavaScript Python Ajax Flask 客户端

评论


答:

0赞 Fine 10/5/2018 #1

用非常非常简单的话来说,从服务器呈现的网页 Flask 迁移到 API+SPA 是更改处理程序,因此它们返回的不是呈现的页面,而只是该网页在客户端呈现所需的数据。

Vanilla JS 方法(我不建议用于真正的生产应用程序,有 SPA 框架,如 React、Angular、Vue 等)。

改变:

return render_template("address1.html", text=CP_Info)

自:

return json.dumps({'text': CP_Info})

然后从 HTML 中删除所有 Jinja 代码并将其作为静态文件提供。此外,您应该将 JS 代码添加到 HTML 文件中,以从路由中获取数据(使用 XHR 或 jQuery 或您喜欢的内容),并使用纯 JS 或类似框架添加基于它的 HTML 标签(元素)。/address

如果您正确地完成了所有操作,则打开的页面将与之前在路由上打开的页面几乎相同。localhost:your_app_port/static/your_html_name.html/address

评论

0赞 sgeza 10/5/2018
好的,谢谢!你会说用 NodeJS(也许?那会让它成为一个SPA,不是吗?
0赞 Fine 10/5/2018
我不能说它是否更容易,因为有围绕服务器渲染构建的大型网站,将它们重写为 SPA 的成本可能太高了。但是,如果您要从头开始构建这样的 SPA 应用程序,您绝对应该使用 SPA 框架。
1赞 Tohmaxxx 10/5/2018 #2

如果要创建 SPA,可以在 HTML 文件中托管 SPA HTML/JS。 然后,在 /address 路由中提供 JSON

@app.route('/address',methods = ['POST', 'GET'])
def address1():
    if request.method == 'POST':
        desired_CP_Address = request.form["address"]

        response = requests.get("https://data.gov.sg/api/action/datastore_search?resource_id=139a3035-e624-4f56-b63f-89ae28d4ae4c&q=" + desired_CP_Address)
        r = response.json()

        return jsonify(r['result']['records'])



@app.route('/spa',methods = ['GET'])
def spa():
    return render_template('spa.html')

现在,您的spa.html可以使用 JavaScript XHR 从 /address (cfr https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch ) 查询 json,例如。

<script>
    fetch('/address', {
      method: "POST", // *GET, POST, PUT, DELETE, etc.
      mode: "cors", // no-cors, cors, *same-origin
      cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
      credentials: "same-origin", // include, same-origin, *omit
      headers: {
        "Content-Type": "application/json; charset=utf-8",
        // "Content-Type": "application/x-www-form-urlencoded",
      },
      redirect: "follow", // manual, *follow, error
      referrer: "no-referrer", // no-referrer, *client
      body: JSON.stringify(data), // body data type must match "Content-Type" header
})
      .then(function(response) {
        return response.json();
      })
      .then(function(myJson) {
        console.log(JSON.stringify(myJson));
      });
</script>

我建议你使用 javascript 前端的框架(例如 react),而不是从头开始编写所有内容。

评论

0赞 sgeza 10/5/2018
啊,所以基本上,我们不是使用 Flask 返回render_template而是使用它来返回数据?
0赞 Tohmaxxx 10/5/2018
是的,Flask 返回 JSON 数据,该数据由 JavaScript 检索。我在这里的 flask 中制作了一个 SPA 应用程序:thomaxxl.pythonanywhere.com/ja/index.html#/people ,检查浏览器开发工具中的网络流量,你就会看到它是关于什么的:flask 提供 json,spa 获取它并呈现它。