Flask入门教程(二十四):请求对象API——获取客户端数据的完整指南

1. 常用属性速查

属性 类型 说明 示例值
method str HTTP请求方法 "GET"、"POST"
path str URL路径部分(不含域名和查询字符串) "/search"
full_path str 路径 + 查询字符串 "/search?q=runoob"
url str 完整请求URL "http://localhost:5000/search?q=runoob"
base_url str URL去掉查询字符串 "http://localhost:5000/search"
url_root str 域名 + 应用根路径 "http://localhost:5000/"
host str Host头,含端口 "localhost:5000"
host_url str scheme + host + 应用根 "http://localhost:5000/"
scheme str 协议 "http"、"https"
remote_addr str 客户端IP地址 "127.0.0.1"
endpoint str 匹配到的路由endpoint "index"、"blog.show"
url_rule Rule 匹配到的路由规则对象 Werkzeug Rule实例
view_args dict URL中的动态变量 {"post_id": 42}
blueprint str 当前蓝图名称 "auth"、"blog"
is_json bool 请求Content-Type是否为JSON True / False

2. 获取请求数据

属性/方法 类型 说明
args MultiDict URL查询参数
form MultiDict POST表单数据
json dict / None JSON请求体(已解析)
data bytes 原始请求体数据
files FileMultiDict 上传的文件
cookies dict 客户端发来的Cookie
headers Headers 请求头
get_json(force=False, silent=False, cache=True) --- 解析JSON请求体

获取查询参数(args)

复制代码
from flask import request

@app.route("/search")
def search():
    keyword = request.args.get("q", "")
    page = request.args.get("page", 1, type=int)
    return f"搜索: {keyword}, 第{page}页"

获取表单数据(form)

复制代码
@app.route("/login", methods=["POST"])
def login():
    username = request.form.get("username", "")
    password = request.form.get("password", "")
    return f"用户: {username}"

获取JSON数据(json / get_json)

复制代码
@app.post("/api/user")
def create_user():
    # 方式一:直接使用 request.json
    data = request.json
    name = data.get("name", "unknown") if data else "unknown"

    # 方式二:使用 get_json()
    data = request.get_json()
    if data:
        name = data.get("name", "unknown")
    return {"name": name}

获取上传的文件(files)

复制代码
from werkzeug.utils import secure_filename

@app.route("/upload", methods=["POST"])
def upload():
    if "file" not in request.files:
        return "没有文件", 400

    file = request.files["file"]
    if file.filename == "":
        return "文件名为空", 400

    filename = secure_filename(file.filename)
    file.save(f"uploads/{filename}")
    return f"文件 {filename} 上传成功"

获取Cookie(cookies)

复制代码
@app.route("/profile")
def profile():
    theme = request.cookies.get("theme", "light")
    return f"当前主题: {theme}"

获取请求头(headers)

复制代码
@app.route("/info")
def info():
    user_agent = request.headers.get("User-Agent", "")
    referer = request.headers.get("Referer", "")
    accept = request.headers.get("Accept", "")
    return f"User-Agent: {user_agent}"

3. 内容协商属性

属性/方法 说明
accept_mimetypes 客户端接受的MIME类型列表
accept_charsets 客户端接受的字符集
accept_encodings 客户端接受的编码方式
accept_languages 客户端接受的语言
content_type 请求的Content-Type
content_length 请求体长度(字节)
复制代码
@app.route("/negotiate")
def negotiate():
    # 获取客户端首选语言
    best_lang = request.accept_languages.best
    # 判断客户端是否接受JSON
    accepts_json = request.accept_mimetypes.best == "application/json"
    return {"best_language": best_lang, "accepts_json": accepts_json}

4. 常用MultiDict操作

request.args和request.form都是MultiDict类型,支持一个键对应多个值:

复制代码
# 获取单个值(推荐)
request.args.get("key", default="")      # 返回第一个值,不存在返回默认值

# 获取所有值
request.args.getlist("key")              # 返回所有值的列表

# 检查是否存在
"key" in request.args                    # 返回True/False

# 遍历所有键
for key in request.args:
    print(key, request.args.get(key))

# 转换为普通dict
request.args.to_dict()                   # 只保留第一个值
request.args.to_dict(flat=False)         # 保留所有值

5. 请求对象完整示例

复制代码
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/api/demo", methods=["GET", "POST", "PUT", "DELETE"])
def demo():
    # ===== 请求方法 =====
    method = request.method

    # ===== URL信息 =====
    path = request.path
    full_path = request.full_path
    url = request.url
    remote_ip = request.remote_addr

    # ===== 查询参数 =====
    q = request.args.get("q", "")

    # ===== 表单数据 =====
    username = request.form.get("username", "")

    # ===== JSON数据 =====
    data = request.get_json(silent=True)  # 非JSON时返回None,不抛异常
    name = data.get("name") if data else None

    # ===== 文件上传 =====
    uploaded_file = None
    if "avatar" in request.files:
        file = request.files["avatar"]
        if file.filename:
            from werkzeug.utils import secure_filename
            uploaded_file = secure_filename(file.filename)

    # ===== Cookie =====
    theme = request.cookies.get("theme", "light")

    # ===== 请求头 =====
    user_agent = request.headers.get("User-Agent", "")
    accept_lang = request.headers.get("Accept-Language", "")

    return jsonify({
        "method": method,
        "path": path,
        "full_path": full_path,
        "url": url,
        "remote_ip": remote_ip,
        "query": q,
        "username": username,
        "json_name": name,
        "uploaded_file": uploaded_file,
        "theme": theme,
        "user_agent": user_agent,
        "accept_language": accept_lang,
        "is_json": request.is_json,
        "content_type": request.content_type,
        "endpoint": request.endpoint,
        "view_args": request.view_args,
    })

6. 请求对象API速查表

类别 属性/方法 说明
基本信息 method、path、url、remote_addr 请求基础信息
查询参数 request.args.get("key", default) GET参数
表单数据 request.form.get("key", default) POST表单
JSON数据 request.json、request.get_json() JSON请求体
原始数据 request.data 原始请求体
文件上传 request.files.get("key") 上传文件
Cookie request.cookies.get("key") 客户端Cookie
请求头 request.headers.get("key") 请求头
内容协商 request.accept_languages.best 客户端偏好

7. 常见错误与最佳实践

❌ 错误做法 ✅ 正确做法
request.args["key"](KeyError) request.args.get("key", default)
不检查request.files是否存在 先判断"file" in request.files
不检查file.filename是否为空 判断if file.filename != ""
直接使用上传的文件名 使用secure_filename()处理
不判断request.is_json直接用request.json 用request.get_json(silent=True)

小结

本章全面讲解了Flask请求对象的完整API。request代理对象提供了method、path、url、remote_addr等基础信息属性;获取客户端数据通过args(URL查询参数)、form(POST表单)、json/get_json()(JSON请求体)、files(上传文件)、cookies和headers;内容协商属性包括accept_languages、accept_mimetypes等;对于MultiDict类型,推荐使用.get(key, default)方法安全获取值。熟练掌握请求对象的API,是正确处理客户端输入的基础。

相关推荐
数据库小学妹3 分钟前
向量检索最小可运行实现:HNSW索引参数与召回率/延迟权衡
数据库·后端
姜鱼问生4 分钟前
Docker Volume 备份与恢复实战:不停机迁移数据
后端·算法·架构
suhan4 分钟前
【数据结构】三、栈和队列:5.顺序队列(循环队列)(初始化,判空判满,入队,出队,实例)
数据结构·后端·算法
看浪的路人5 分钟前
第7讲:大模型后端服务化——Go 实现高并发 LLM Proxy / Router / Fallback
开发语言·后端·golang
suhan5 分钟前
【数据结构】三、栈和队列:3.链栈(链栈栈的初始化,判空,进栈,出栈,读取栈顶,链栈实例)
数据结构·后端·算法
邱杰4705 分钟前
数智人事系统(十一):Spring Boot + MyBatis-Plus 的 CRUD 落地
后端·github
姜鱼问生6 分钟前
服务器磁盘满了?从告警到清理的完整排查
后端·算法·架构
邱杰4707 分钟前
数智人事系统(十三):考勤打卡与出勤日历
后端·github
suhan7 分钟前
【数据结构】三、栈和队列:4.栈的应用(括号匹配,四则运算表达式求值,进制转换,递归)
数据结构·后端·算法
用户019027581619 分钟前
如何用 Python 计算 EMV 简易波动指标?
python