Python Web Flask — GET、POST傳送資料

Sean Yeh
Python Everywhere -from Beginner to Advanced
14 min readSep 7, 2020

--

Photo by 冬城 on Unsplash

網頁傳送資料的方式有二:GET與POST。在Flask裡面,也不例外,Flask的路由預設使用GET方式進行路徑存取。

以前的文章曾經說過,伺服器接受Request並且依照Request提供對應的 Response,這個Request 與 Response的溝通行為,是HTTP Request的一個生命週期。

以GET傳送資料

以GET傳送數值的方式是將要傳送的參數至於網址後面,其中第一個參數以問號『?』作為連接符號,第二個以後的參數都以『&』符號為連接符號。例如:我們要傳送name與email參數時,其語法如下:

http://127.0.0.1:5000/?name=MyName&email=myname@abc.com

要取得參數值需要先匯入request套件。因為Flask是透過request來取得參數值。

from flask import request

匯入request套件後,如果Flask想要接收以GET方式傳送的參數,就需要在method設定以GET方式傳送。其語法如下:

@app.route('/',method=['GET'])

上面的意思是,在首頁使用GET方式傳送參數。

接著,就可以使用「args.get」方法取得參數值,其語法如下:

request.args.get('name')

上面的意思是,取得透過GET方式傳送來的name參數值。

GET範例說明:

綜合上面的幾個步驟,我們可以實際來適用一下,透過GET取得參數值。

首先,匯入request套件。

from flask import Flaskfrom flask import render_templatefrom flask import request

如果覺得太長的話,你也可以這樣子寫:

from flask import Flask, render_template, request

接著,我們建立一個新的路由「/getname」,並且在@app.route路由裡面的method設定以GET方式傳送。在路由下面建立一個getname函式:

@app.route("/getname", methods=['GET'])def getname():    name = request.args.get('name')    return render_template('get.html',**locals())

getname函式,透過「args.get」方法取得name參數值,並且return到get.html的remplates裡面。

因此,我們還需要一個名為get.html的template。請在templates資料夾裡面建立一個get.html。

{% extends "base.html" %}
{% block body %}
<div class="row">
<div class="col">
<h1>{{name}}, Welcome. This is Home Page</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus ducimus eveniet laudantium voluptatem labore, atque perferendis reiciendis quas ipsam a est assumenda eos distinctio molestiae nam itaque, cum voluptates eligendi.</p>
</div>
<div class="col">
<h1>This is {{name}}'s first Page</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Maiores nemo maxime culpa, iure, minima ducimus magni non hic similique tempore impedit necessitatibus eum! Sunt adipisci porro aperiam fugit magnam delectus.</p>
</div>
</div>
{% endblock %}

我們就姑且使用以前曾經建立過的hello.html樣板,複製為get.hrml。由於這是練習的關係,重點只有一個,就是樣板中必須存在{{name}}。其他都可以隨心所欲的依照個人在html+CSS學到的技術來製作。

最後,存檔之後我們可以進行測試。請輸入網址,並且加上參數name=Sean(你可以用別的名字),其中第一個參數以問號『?』作為連接符號。

http://127.0.0.1:5000/getname?name=Sean

結果你可以發現原本樣板中{{name}}的地方已經變成網址列上面的Sean了。

這表示我們已經成功的透過GET方式,將參數傳到網頁上面。你可以試著傳送多個參數。例如我們可以增加一個fruit參數:

@app.route("/getname", methods=['GET'])def getname():    name = request.args.get('name')    fruit =request.args.get('fruit')    return render_template('get.html',**locals())

還記得之前說過,第二個以後的參數都以『&』符號為連接符號,所以fruit要以『&』符號為連接符號來連接。結果:

應該不難吧。

以POST傳送資料

如果以GET傳送資料的話,資料會曝露在網址列上面。如果沒有什麼安全性顧慮的參數的話,就還沒什麼問題,一旦傳送的資料屬於個資、或者是安全等級比較高的資料,就不是非常適合使用GET方式傳送。在這種狀況下,透過另一總方式傳送資料就有其必要性。透過POST方式傳送資料不會顯示在網址列,相對於以GET傳送資料來說,比較安全。一般來說,我們會利用表單來輸入資料,並且透過POST來將資料表單傳送給伺服器。

首先,匯入request套件。(方法如上面的GET說明)

from flask import Flask, render_template, request

在method設定以POST方式傳送。表單的 action 要設定到處理函式的名稱。例如submit。

<form method="POST" action="{{url_for('submit')}}">

接著要建立路由與對應的處理函式:

@app.route("/submit", methods=['POST'])def submit():    // do something

我們可以透過request裡面的values方法取得POST的參數值。

firstname = request.values['firstname']

例如:我們想要取得POST表單中name為firstname欄位的值,可以透過上面的方式撰寫。

範例說明:

綜合上面的步驟,我們可以實際來適用一下,透過POST取得參數值。

先製作form表單。

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

我們透過我們透過Bootstrap來製作一個簡單的表單。裡面有一個form,form裡面有兩個input與一個button。

<form method="POST" action="{{url_for('submit')}}"><input type="text" class="form-control" name="firstname" placeholder="First name"><input type="text" class="form-control" name="lastname" placeholder="Last name"><button type="submit" class="btn btn-primary">Submit</button>

其他的部分大家可以隨心所欲的依照個人在html+CSS學到的技術來製作。

{% extends "base.html" %}
{% block body %}
<div class="row">
<div class="col">
<form method="POST" action="{{url_for('submit')}}">
<div class="form-row">
<div class="col-12 mt-3">
<input type="text" class="form-control" name="firstname" placeholder="First name">
</div>
<div class="col-12 mt-3">
<input type="text" class="form-control" name="lastname" placeholder="Last name">
</div>
<div class="col-12 mt-3 pt-3">
<button type="submit" class="btn btn-primary">Submit
</button>
</div>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

執行後的結果如下:

接下來,製作submit函式與頁面。我們透過request裡面的values方法取得firstname與lastname的參數值,並且將結果顯示在submit.html樣板中。

@app.route("/submit", methods=['POST'])def submit():    firstname = request.values['firstname']    lastname = request.values['lastname']    return render_template('submit.html',**locals())

接著設計submit.html樣板頁面,關鍵是必須放入{{firstname}} 與{{lastname}},其他的部分可以依照需要隨心所欲的來製作。

{% extends "base.html" %}
{% block body %}
<div class="row">
<div class="col"> <h1>Hello {{firstname}} {{lastname}}, Welcome. This is Your Page</h1> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus ducimus eveniet laudantium voluptatem labore, atque perferendis reiciendis quas ipsam a est assumenda eos distinctio molestiae nam itaque, cum voluptates eligendi.</p> </div></div>
{% endblock %}

以上都製作完畢。就可以執行程式。

執行後,輸入first name 與 last name後,結果顯示如下:

route中同時宣告POST與GET兩種HTTP存取方式

另外,我們也可以採用下面的方式:在route中宣告使用兩種HTTP存取方式,POST與GET兩種。無論使用者採用以上何種方式瀏覽網址/form2,都會被配對到form2函式並執行。

在form2函式中,會透過request.method屬性,獲得本次HTTP請求的存取方式。並藉由if statement分別不同方式,採用不同的處理行動。在下面的例子,如果HTTP請求的存取方式是POST的話,就會轉指到submit去,如果HTTP請求是GET的話,則會到form2.html樣板。

@app.route("/form2", methods=["POST","GET"])def form2():    if request.method == "POST":        firstname = request.form['firstname']        lastname = request.form['lastname']        return redirect(url_for('submit',**locals()))    else:        return render_template('form2.html')

--

--

Sean Yeh
Python Everywhere -from Beginner to Advanced

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。