查詢字串 (query string) 是指加在 URL 後,用來傳遞非結構化參數資料給伺服器的一段字串,以問號 ?
開始,包含一或多組「鍵值」對,每一組之間以 &
符號分隔。通常來說是用以下方式傳遞:
1
| 通訊協定://主機名稱:埠號/路徑?參數鍵1=值1&參數鍵2=值2&...
|
用以下的網址為例:
1
| https://example.com/search?keyword=flask&page=2
|
其中查詢字串是 ?keyword=flask&page=2
注意到,所有值在 URL 中一律都是字串型別,因此若需要對值進行操作,就需要轉換型別。
後端基本處理
在 Flask 中,我們已經學到可以使用請求物件,將前端所發送的請求所附帶的資訊傳遞到後端處理。而處理查詢字串的方法是使用 request.args
獲得前端送來的資訊。基本語法為:
1
| request.args.get("參數名稱", 預設值)
|
舉例而言,我們可以實作一個 /getSum
路徑,允許使用者傳入最大值,從 1 開始累加至該數字:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @app.route("/getSum") def getSum(): max_number = request.args.get("max", 100) max_number = int(max_number) logging.debug(f"最大數字: {max_number}")
result = 0 for num in range(1, max_number + 1): result += num
return f"加總至 {max_number} 的結果為 {result}"
|
在瀏覽器網址列輸入 127.0.0.1:5000/getSum?max=50
後,便可得到以下結果:
圖 1:累加至最大值
當然,傳遞的參數可以不只一個。將上面的寫法變化一下,允許接收最小值與最大值,從最小值開始累加至最大值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @app.route("/getSum") def getSum(): min_number = request.args.get("min", 1) max_number = request.args.get("max", 100) min_number = int(min_number) max_number = int(max_number) logging.debug(f"最小數字: {min_number}") logging.debug(f"最大數字: {max_number}")
result = 0 for num in range(min_number, max_number + 1): result += num
return f"由 {min_number} 加總至 {max_number} 的結果為 {result}"
|
輸入 127.0.0.1:5000/getSum?min=3&max=98
即可得到以下結果:
圖 2:支援最小值累加至最大值
進階操作與處理
了解完基本的查詢字串操作後,不免會有以下幾個問題或想法:
- 使用者傳入一堆參數,但只想要接收特定幾個
- 使用者亂傳參數,無法進行型別轉換
- 出現未知參數
針對多個參數,我們的做法是使用 to_dict()
方法,將查詢字串變成一個字典,例如:
1
| {'min': '1', 'max': '100', 'step': '1', ...}
|
而如果只想要處理幾個特定的參數,可以先設定一個合法參數集合(用 set
),接著使用迴圈檢查。例如以下範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @app.route("/getSum") def getSum(): allowed_keys = {"min", "max", "step"} data = request.args.to_dict()
for key in data: if key not in allowed_keys: return f"未知的參數: {key}", 400 try: min_number = int(data.get("min", 1)) max_number = int(data.get("max", 100)) step = int(data.get("step", 1)) except ValueError: return "參數必須是整數", 400 result = 0 for num in range(min_number, max_number + 1, step): result += num return f"由 {min_number} 加總至 {max_number} 的結果為 {result},步數為 {step}"
|
若輸入 http://127.0.0.1:5000/getSum?min=5&max=35&step=5
即可得到:
圖 3:多種不同參數
但如果輸入 http://127.0.0.1:5000/getSum?flask=100
,因為 flask
並非允許的合法參數,所以會出現以下內容:
圖 4:未知參數處理
最後一個則是多個參數值,想像下面這個網址,代表使用者選了多個標籤:
1
| /search?tag=python&tag=flask&tag=web
|
如果用:
1
| tag = request.args.get("tag")
|
只能拿到第一個 "python"
。正確的做法是用 getlist("參數名稱")
,將同一個鍵的值搜集起來變成列表。例如新建一個路徑 /getAverage
,計算使用者傳入的所有數字的算術平均數:
1 2 3 4 5 6 7 8 9 10
| @app.route("/getAverage") def getAverage(): nums_data = request.args.getlist("num") try: nums = [int(n) for n in nums_data] except ValueError: return "參數必須是整數", 400 avg = sum(nums) / len(nums) return "、".join(sorted(nums_data)) + f" 的平均為: {avg}"
|
圖 5:多參數值