-1

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

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

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

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

目前正在努力实施,任何帮助都会很棒!

下面的 .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 %}
4

2 回答 2

1

如果你想制作一个水疗中心,你可以将水疗中心的 html/js 托管在一个 html 文件中。然后你在 /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 查询 json(cfr https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch),例如。

<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),而不是从头开始编写所有内容。

于 2018-10-05T08:13:52.367 回答
0

用非常非常简单的话来说,从服务器呈现的网页 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 代码并将其作为静态文件提供。此外,您应该在 HTML 文件中添加 JS 代码以从路由中获取数据(使用 XHR 或 jQuery 或您喜欢的),并使用普通 JS或类似 jQuery 或类似的框架/address添加基于它的 HTML 标签(元素) 。

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

于 2018-10-05T08:07:15.017 回答