Flask(7)- request 對象
- 2021 年 7 月 11 日
- 筆記
- Flask, 測試高級進階技能系列 - Flask
Flask 中很重要的 request 對象
- 瀏覽器訪問服務端時,向服務端發送請求
- Flask 程式使用 request 對象描述請求資訊
- 當你想獲取請求體、請求參數、請求頭數據的時候,就需要靠 request 對象了
- 這一篇會用結果驅動源碼解析的方式來講解
真實使用場景
瀏覽器訪問服務端,需要將相應的數據發送給服務端,可能有如下場景:
- 通過 URL 參數進行查詢,瀏覽器需要將查詢參數發送給服務端
- 提交表單 form 進行查詢,瀏覽器需要將表單 form 中的欄位發送給服務端
- 上傳文件,瀏覽器需要將文件發送給服務端
- 通過 JSON 格式的請求體進行請求,一般是 post 請求
服務端收到將客戶端發送的數據後,封裝形成一個請求對象,在 Flask 中,請求對象是一個模組變數 flask.request
request 包含的常用屬性
屬性 | 說明 |
---|---|
method | 當前的請求方法 |
form | 表單參數及其值的字典對象 |
args | 查詢字元串的字典對象 |
values | 包含所有數據的字典對象 |
json | 如果 mimetype 是 application/json,這個參數將會解析 json 數據,如果不是則返回 None |
headers | http 協議 請求頭 |
cookies | cookie 名稱和值的字典對象 |
files | 與上傳文件有關的數據 |
form、args、values、json 都是獲取 http 請求的請求數據的屬性,只不過請求體類型不同
還記得之前講 url 組成的時候,request 對象也能獲取 url 相關參數嗎,複習下
request 獲取 url 組成的常用屬性
假設 URL 等於 //localhost/query?userId=123,request 對象中與 URL 參數相關的屬性如下
屬性 | 說明 |
---|---|
url | //localhost/query?userId=123 |
base_url | //localhost/query |
host | localhost |
host_url | //localhost/ |
path | /query |
full_path | /query?userId=123 |
獲取 url 請求參數的栗子
程式碼
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠蘿測試筆記 # blog: //www.cnblogs.com/poloyy/ # time: 2021/7/11 11:13 上午 # file: 5_request.py """ from flask import Flask, request app = Flask(__name__) @app.route('/query') def query(): return {"name": request.args['name'], "age": request.args['age']} @app.route('/query2') def query2(): print('args =', request.args) print('form =', request.form) return "form" @app.route('/query3') def query3(): print('args =', request.args) print('json =', request.json) return "json" @app.route('/query4') def query4(): return {"name": request.values['name'], "age": request.values['age']} if __name__ == '__main__': app.run(debug=True)
- 下面我會用 postman 統一通過 params,就是 url 請求參數傳數據
- 在 Flask 裡面,把四種獲取請求數據的屬性都寫一遍,然後看看最後的結果,提前幫大家踩坑
postman 發起請求的結果
/query
/query2
控制台輸出
args = ImmutableMultiDict([('name', 'zhangsan'), ('age', '13')]) form = ImmutableMultiDict([])
用 form 屬性的話得到是一個空字典哦
/query3
控制台輸出
args = ImmutableMultiDict([('name', 'zhangsan'), ('age', '13')]) json = None
用 json 屬性的話得到是一個 None 哦,所以無論如何都不要用 json 獲取 url 請求參數喲!
/query4
可以看到 values 屬性也能拿到 url 請求參數哦
獲取表單參數的栗子
程式碼
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠蘿測試筆記 # blog: //www.cnblogs.com/poloyy/ # time: 2021/7/11 1:47 下午 # file: 5_request_form.py """ from flask import Flask, request app = Flask(__name__) @app.route('/addUser', methods=['POST']) def check_login(): return {"name": request.form['name'], "age": request.form['age']} @app.route('/addUser2', methods=['POST']) def check_login2(): print('form =', request.form) print('args =', request.args) return "good" @app.route('/addUser3', methods=['POST']) def check_login3(): print('form =', request.form) print('json =', request.json) return "good" @app.route('/addUser4', methods=['POST']) def check_login4(): return {"name": request.values['name'], "age": request.values['age']} if __name__ == '__main__': app.run(debug=True)
- 下面我會用 postman 統一通過 form-data,就是表單格式來傳數據
- 在 Flask 裡面,把四種獲取請求數據的屬性都寫一遍,然後看看最後的結果,提前幫大家踩坑
postman 發起請求的結果
/addUser
/addUser2
控制台輸出
form = ImmutableMultiDict([('name', 'poloyy'), ('age', '12')]) args = ImmutableMultiDict([])
用 args 屬性的話得到是一個空字典哦
/addUser3
控制台輸出
form = ImmutableMultiDict([('name', 'poloyy'), ('age', '12')]) json = None
用 json 屬性的話得到是一個 None 哦,所以無論如何都不要用 json 獲取 form-data 喲!
/addUser4
可以看到 values 屬性也能拿到 form 表單提交的數據哦
獲取 Json 數據的栗子
程式碼
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠蘿測試筆記 # blog: //www.cnblogs.com/poloyy/ # time: 2021/7/11 1:47 下午 # file: 5_request_form.py """ from flask import Flask, request app = Flask(__name__) @app.route('/addJson', methods=['POST']) def check_login(): return {"name": request.json['name'], "age": request.json['age']} @app.route('/addJson2', methods=['POST']) def check_login2(): print('json =', request.json) print('args =', request.args) return "good" @app.route('/addJson3', methods=['POST']) def check_login3(): print('json =', request.json) print('form =', request.form) return "good" @app.route('/addJson4', methods=['POST']) def check_login4(): print('json =', request.json, type(request.json)) print('values =', request.values) return {"name": request.json['name'], "age": request.json['age']}
if __name__ == '__main__': app.run(debug=True)
- 下面我會用 postman 統一通過 raw-json,就是 Json 格式的請求體來傳數據
- 在 Flask 裡面,把四種獲取請求數據的屬性都寫一遍,然後看看最後的結果,提前幫大家踩坑
postman 發起請求的結果
/addJson
/addJson2
json = {'age': '12', 'name': 'poloyy'} args = ImmutableMultiDict([])
用 args 屬性的話得到是一個空字典哦
/addJson3
json = {'age': '12', 'name': 'poloyy'} form = ImmutableMultiDict([])
用 form 屬性的話得到是一個空字典哦
/addJson4
這裡要注意的是,當你的請求體是 Json 時,是不能通過 values 來獲取請求數據哦!!
最後來看看 request.json 會返回什麼吧
json = {'age': '12', 'name': 'poloyy'} <class 'dict'>
request.json 拿到的就是 Json 格式的請求體,並且自動轉換成字典了哦!
為什麼 requests.values 能獲取 form、args 的數據,但是拿不到 json 的數據呢?
request.values 源碼
- 能看到,它本質就是獲取 args、form 的數據,但不包含 json 數據
- 但是這裡有個重點,只有你的請求方法不為 GET 的時候,發送 form 表單數據才能通過 request.values 拿到請求數據
- 來試試是不是真的這樣
程式碼
@app.route('/query4', methods=["GET", "POST"]) def query4(): print(request.form) print(request.args) print(request.values) return {"name": request.values['name'], "age": request.values['age']}
postman 發起 GET 請求,form-data 傳數據
直接報錯,找不到對應的 name key,因為 request.values 是空的
控制台輸出
ImmutableMultiDict([('name', 'poloyy'), ('age', '12')]) CombinedMultiDict([ImmutableMultiDict([])]) ImmutableMultiDict([])
很明顯,request.form 是能拿到數據的,但是 request.value 是拿不到數據哦
postman 發起 POST 請求,form-data 傳數據
這次就能正常顯示返回值啦
控制台輸出
ImmutableMultiDict([('name', 'poloyy'), ('age', '12')]) ImmutableMultiDict([]) CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([('name', 'poloyy'), ('age', '12')])])
看源碼應該知道,當非 GET 請求的時候傳遞表單數據,request.values 也能獲取得到 request.form 的數據