request 是全局对象,为什么线程安全?
答案:环境局部变量(上下文代理 / Thread Local)
request表面上是全局导入的对象,但它不是普通全局变量,是一个代理对象。- Flask 为每一条请求对应的线程,独立绑定一套专属请求环境(WSGI上下文)。
- 不同请求线程之间环境隔离,数据互不干扰,相当于每个请求拥有独立“数据管道”,不会跨请求互相篡改数据,以此实现线程安全。
简单理解:你看到的
request只是一个“入口门面”,真正存储请求数据的内容,每个线程独立存放。
导入
from flask import requestCode language: JavaScript (javascript)
POST表单参数
request.form
适用于 POST 请求提交的表单数据(application/x-www-form-urlencoded)
示例登录路由
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
# 获取表单提交的用户名、密码
username = request.form['username']
password = request.form['password']
if valid_login(username, password):
return log_the_user_in(username)
else:
error = '无效的用户名/密码'
# GET请求直接返回登录页面
return render_template('login.html', error=error)Code language: PHP (php)
- 使用
request.form['key']取值:键不存在时抛出特殊 KeyError - Flask 捕获该异常,直接返回 400 Bad Request 错误页面
- 推荐稳妥写法(避免报错):
username = request.form.get("username", "")Code language: JavaScript (javascript)
Get URL查询参数
request.args
获取URL问号后的参数 ?id=12&key=abc
# 取不到参数时,默认值为空字符串
searchword = request.args.get('q', '')Code language: PHP (php)
request.args→ URL地址栏GET参数request.form→ POST提交表单参数
汇总
| 属性 | 作用 |
|---|---|
request.method | 获取当前请求方式 GET / POST |
request.url | 获取完整请求URL |
request.headers | 获取请求头信息 |
request.remote_addr | 获取客户端IP地址 |
request.json | 获取JSON格式请求体(前端传json) |
完整实例
from flask import Flask, request, render_template
app = Flask(__name__)
def valid_login(username, password):
# 模拟账号校验
return username == "admin" and password == "123456"
def log_the_user_in(username):
return f"登录成功,欢迎 {username}"
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
uname = request.form.get("username")
pwd = request.form.get("password")
if valid_login(uname, pwd):
return log_the_user_in(uname)
else:
error = "无效的用户名/密码"
return render_template("login.html", error=error)
@app.route("/search")
def search():
# 获取GET参数
q = request.args.get("q", "空搜索词")
return f"你搜索的内容:{q}"
if __name__ == '__main__':
app.run(debug=True)Code language: C# (cs)