Flask請(qǐng)求數(shù)據(jù)獲取方法詳解
一、工作原理
在 Flask 中,所有客戶端請(qǐng)求的數(shù)據(jù)都通過全局的 request 對(duì)象訪問。該對(duì)象是 請(qǐng)求上下文 的一部分,僅在請(qǐng)求處理期間存在。Flask 在收到請(qǐng)求時(shí)自動(dòng)創(chuàng)建 request 對(duì)象,并根據(jù)請(qǐng)求類型(如 GET、POST)和內(nèi)容類型(如表單、JSON)解析數(shù)據(jù),將不同來源的數(shù)據(jù)封裝到對(duì)應(yīng)的屬性中(如 args、form、json)。
二、常用方法
查詢參數(shù)(URL參數(shù))
使用 request.args(類型:ImmutableMultiDict)獲取 URL 中的查詢參數(shù)。
name = request.args.get('name') # 獲取單個(gè)參數(shù)
all_args = request.args.to_dict() # 轉(zhuǎn)為字典
表單數(shù)據(jù)
針對(duì) application/x-www-form-urlencoded 或 multipart/form-data 類型的 POST 請(qǐng)求,使用 request.form。
username = request.form.get('username')
JSON 數(shù)據(jù)
當(dāng)請(qǐng)求的 Content-Type 為 application/json 時(shí),使用 request.json 直接獲取解析后的字典。
data = request.json
文件上傳
通過 request.files 獲取上傳的文件(類型:FileStorage)。
file = request.files.get('file')
if file:
file.save('uploaded_file.txt')
原始數(shù)據(jù)
使用request.data獲取未經(jīng)處理的原始字節(jié)數(shù)據(jù)(如非表單、非JSON的請(qǐng)求體)。請(qǐng)求頭與Cookies
user_agent = request.headers.get('User-Agent')
user_token = request.cookies.get('token')
三、高級(jí)用法
處理多值參數(shù)
當(dāng)參數(shù)有多個(gè)值時(shí)(如多選框),使用getlist:
selected_ids = request.form.getlist('ids')
- 強(qiáng)制解析JSON
即使Content-Type不是application/json,也可強(qiáng)制解析:
data = request.get_json(force=True)
- 流式處理大文件
使用request.stream逐塊讀取數(shù)據(jù),避免內(nèi)存溢出:
@app.route('/upload', methods=['POST'])
def upload():
def generate():
chunk_size = 4096
while True:
chunk = request.stream.read(chunk_size)
if not chunk:
break
# 處理chunk...
return 'Upload complete'
混合數(shù)據(jù)(表單+JSON)使用
request.values合并查詢參數(shù)和表單數(shù)據(jù)(不推薦混用,需謹(jǐn)慎處理邏輯)。
四、完整示例
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api', methods=['GET', 'POST'])
def handle_request():
# 獲取查詢參數(shù)
query_param = request.args.get('q')
# 根據(jù)不同請(qǐng)求類型處理數(shù)據(jù)
if request.method == 'POST':
# 處理表單數(shù)據(jù)
username = request.form.get('username')
# 處理JSON數(shù)據(jù)
json_data = request.get_json(silent=True) # 解析失敗返回None
# 處理文件上傳
uploaded_file = request.files.get('file')
if uploaded_file:
uploaded_file.save('uploads/' + uploaded_file.filename)
return jsonify({
"query_param": query_param,
"username": username,
"json_data": json_data,
"file_uploaded": bool(uploaded_file)
})
else:
return jsonify({"query_param": query_param})
if __name__ == '__main__':
app.run(debug=True)
五、注意事項(xiàng)
請(qǐng)求方法影響數(shù)據(jù)獲取
- GET 請(qǐng)求只有
args,無form或files。 - POST 需根據(jù)
Content-Type選擇正確的屬性(如form或json)。
- GET 請(qǐng)求只有
處理缺失數(shù)據(jù)
使用.get('key')而非['key']避免KeyError,可指定默認(rèn)值:
value = request.form.get('key', 'default')
JSON解析安全
- 使用
request.get_json(silent=True)避免解析失敗拋出異常。 - 使用
force=True時(shí)需注意客戶端可能發(fā)送非法數(shù)據(jù)。
- 使用
文件上傳安全
- 限制文件類型和大?。ㄍㄟ^
MAX_CONTENT_LENGTH配置)。 - 驗(yàn)證文件名,避免路徑遍歷漏洞。
- 限制文件類型和大?。ㄍㄟ^
六、擴(kuò)展知識(shí)
請(qǐng)求鉤子預(yù)處理
使用@app.before_request在請(qǐng)求處理前統(tǒng)一驗(yàn)證或預(yù)處理數(shù)據(jù):
@app.before_request
def check_auth():
if not request.endpoint == 'login' and not validate_token(request.headers.get('Token')):
return jsonify({"error": "Unauthorized"}), 401
第三方庫(kù)擴(kuò)展
- Flask-RESTful:構(gòu)建 REST API,自動(dòng)解析請(qǐng)求數(shù)據(jù)。
- Flask-WTF:集成 WTForms,處理表單驗(yàn)證和CSRF保護(hù)。
性能優(yōu)化
- 對(duì)于大文件上傳,使用流式處理或分塊傳輸。
- 啟用
gzip壓縮減少數(shù)據(jù)傳輸量。
測(cè)試請(qǐng)求
使用 Flask 測(cè)試客戶端模擬請(qǐng)求:
with app.test_client() as client:
response = client.post('/api', data={'username': 'test'}, headers={'Content-Type': 'multipart/form-data'})
assert response.status_code == 200
七、錯(cuò)誤處理與調(diào)試技巧
1. 優(yōu)雅處理數(shù)據(jù)解析錯(cuò)誤
在解析客戶端數(shù)據(jù)時(shí),可能會(huì)遇到格式錯(cuò)誤或非法內(nèi)容,需合理捕獲異常:
@app.route('/parse-json', methods=['POST'])
def parse_json():
try:
data = request.get_json()
if data is None:
raise ValueError("Invalid JSON")
# 處理數(shù)據(jù)...
except ValueError as e:
return jsonify({"error": str(e)}), 400
關(guān)鍵點(diǎn):
- 使用
silent=True時(shí),即使解析失敗也不會(huì)拋出異常,但需手動(dòng)檢查data是否為None。 - 針對(duì)文件上傳錯(cuò)誤,可檢查
request.files是否存在且文件對(duì)象有效。
2. 調(diào)試請(qǐng)求數(shù)據(jù)的實(shí)用方法
在開發(fā)過程中,快速查看原始請(qǐng)求數(shù)據(jù)有助于定位問題:
@app.route('/debug', methods=['POST'])
def debug_endpoint():
print("Headers:", request.headers)
print("Raw Data:", request.data.decode('utf-8'))
print("Form Data:", request.form)
return "Debug information logged"
工具推薦:
- Postman:模擬復(fù)雜請(qǐng)求(如 multipart/form-data 或自定義 headers)。
- curl 命令:快速測(cè)試 API 接口:
curl -X POST http://localhost:5000/api -H "Content-Type: application/json" -d '{"key": "value"}'
八、安全加固策略
1. 防范常見攻擊
CSRF 保護(hù):使用
Flask-WTF擴(kuò)展自動(dòng)生成和驗(yàn)證 CSRF Token:
from flask_wtf.csrf import CSRFProtect csrf = CSRFProtect(app)
在表單中添加隱藏字段:
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
SQL 注入防護(hù):始終使用 ORM(如 SQLAlchemy)或參數(shù)化查詢,避免拼接 SQL 字符串。
XSS 防護(hù):對(duì)用戶輸入的內(nèi)容進(jìn)行轉(zhuǎn)義(Flask 模板默認(rèn)自動(dòng)轉(zhuǎn)義)。
2. 文件上傳安全實(shí)踐
- 限制文件擴(kuò)展名:
allowed_extensions = {'png', 'jpg', 'jpeg'}
filename = uploaded_file.filename
if '.' not in filename or filename.split('.')[-1].lower() not in allowed_extensions:
return "Invalid file type", 400
- 防止路徑遍歷:使用
secure_filename處理文件名:
from werkzeug.utils import secure_filename
safe_filename = secure_filename(uploaded_file.filename)
uploaded_file.save(f'uploads/{safe_filename}')
九、異步與性能優(yōu)化
1. 異步處理大請(qǐng)求
使用 async/await 處理耗時(shí)操作(需 Flask 2.0+ 支持異步視圖):
@app.route('/async-upload', methods=['POST'])
async def async_upload():
data = await request.get_data()
# 異步處理數(shù)據(jù)(如寫入數(shù)據(jù)庫(kù))
return "Processing completed"
適用場(chǎng)景:
- 大文件上傳后的后臺(tái)處理(如視頻轉(zhuǎn)碼)。
- 高并發(fā)下的非阻塞 IO 操作。
2. 性能調(diào)優(yōu)建議
配置請(qǐng)求體大小限制:
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 限制為100MB
啟用壓縮:通過 Nginx 或 GzipMiddleware 壓縮響應(yīng)數(shù)據(jù):
from flask_compress import Compress Compress(app)
十、與其他技術(shù)棧集成
1. 結(jié)合前端框架處理數(shù)據(jù)
- React/Vue 表單提交:確保前端
Content-Type與后端匹配:
// 使用FormData處理文件上傳
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('/api/upload', { method: 'POST', body: formData });
- AJAX 請(qǐng)求處理:Flask 自動(dòng)解析
application/json,前端需明確設(shè)置 headers:
fetch('/api/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key: 'value' })
});
2. 擴(kuò)展數(shù)據(jù)格式支持(如 XML)
若需解析 XML 請(qǐng)求,可自定義解析邏輯:
from xml.etree import ElementTree
@app.route('/xml', methods=['POST'])
def parse_xml():
xml_data = request.data
root = ElementTree.fromstring(xml_data)
value = root.find('key').text
return jsonify({"value": value})
十一、實(shí)戰(zhàn)案例:構(gòu)建RESTful API
1. 用戶注冊(cè)接口
處理混合數(shù)據(jù)(JSON + 文件頭像上傳):
@app.route('/register', methods=['POST'])
def register():
# 解析JSON數(shù)據(jù)
user_data = request.get_json()
username = user_data.get('username')
# 處理頭像文件
avatar = request.files.get('avatar')
if avatar:
avatar.save(f'avatars/{secure_filename(avatar.filename)}')
# 保存用戶到數(shù)據(jù)庫(kù)(偽代碼)
save_user(username)
return jsonify({"status": "success"})
2. 分頁(yè)查詢接口
結(jié)合查詢參數(shù)與數(shù)據(jù)過濾:
@app.route('/articles', methods=['GET'])
def get_articles():
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 10, type=int)
articles = Article.query.paginate(page=page, per_page=per_page)
return jsonify({
"data": [article.to_dict() for article in articles.items],
"total_pages": articles.pages
})
十二、總結(jié)
Flask 的請(qǐng)求數(shù)據(jù)獲取機(jī)制兼顧靈活性與簡(jiǎn)潔性,開發(fā)者需根據(jù)實(shí)際場(chǎng)景選擇合適的方法:
- 基礎(chǔ)場(chǎng)景:直接使用
request.args、request.form、request.json。 - 復(fù)雜場(chǎng)景:結(jié)合流式處理、異步操作或第三方庫(kù)擴(kuò)展功能。
- 安全優(yōu)先:始終驗(yàn)證輸入、限制資源、防范常見攻擊。
通過合理設(shè)計(jì)數(shù)據(jù)流和錯(cuò)誤處理機(jī)制,可以構(gòu)建出高效、健壯的 Web 應(yīng)用。
到此這篇關(guān)于Flask請(qǐng)求數(shù)據(jù)獲取方法詳解的文章就介紹到這了,更多相關(guān)Flask請(qǐng)求數(shù)據(jù)獲取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
CentOS 6.5下安裝Python 3.5.2(與Python2并存)
這篇文章主要給大家介紹了在CentOS 6.5下安裝Python 3.5.2的方法教程,安裝后的python3與Python2并存,文中分享了詳細(xì)的方法步驟,對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,下面來一起看看吧。2017-06-06
python獲取指定時(shí)間段內(nèi)特定規(guī)律的日期列表
這篇文章主要介紹了python獲取指定時(shí)間段內(nèi)特定規(guī)律的日期列表,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
python實(shí)現(xiàn)凱撒密碼加密解密的示例代碼
本文主要介紹了python實(shí)現(xiàn)凱撒密碼加密解密的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
python 實(shí)現(xiàn)圖片上傳接口開發(fā) 并生成可以訪問的圖片url
今天小編就為大家分享一篇python 實(shí)現(xiàn)圖片上傳接口開發(fā) 并生成可以訪問的圖片url,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12
Python實(shí)現(xiàn)輕松防止屏幕截圖的技巧分享
屏幕截圖是一種常見的用于記錄信息或者監(jiān)控用戶活動(dòng)的方法,為了保護(hù)隱私和數(shù)據(jù)安全,可以通過使用Python編寫一些防護(hù)措施來防止他人截取我們的屏幕,下面我們就來學(xué)習(xí)一下有哪些具體操作吧2023-12-12
Pytorch技法之繼承Subset類完成自定義數(shù)據(jù)拆分
這篇文章主要介紹了Pytorch技法之繼承Subset類完成自定義數(shù)據(jù)拆分,下文我們介紹一些下面是加載內(nèi)置訓(xùn)練數(shù)據(jù)集的常見操作,需要的小伙伴可以參考一下2022-02-02

