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.argsrequest.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速查表

类别 属性/方法 说明
基本信息 methodpathurlremote_addr 请求基础信息
查询参数 request.args.get("key", default) GET参数
表单数据 request.form.get("key", default) POST表单
JSON数据 request.jsonrequest.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代理对象提供了methodpathurlremote_addr等基础信息属性;获取客户端数据通过args(URL查询参数)、form(POST表单)、json/get_json()(JSON请求体)、files(上传文件)、cookiesheaders;内容协商属性包括accept_languagesaccept_mimetypes等;对于MultiDict类型,推荐使用.get(key, default)方法安全获取值。熟练掌握请求对象的API,是正确处理客户端输入的基础。

相关推荐
geovindu13 分钟前
CSharp: Template Method Pattern
开发语言·后端·c#·.net·模板方法模式·行为模式
步行cgn19 分钟前
Spring Boot application.properties 配置文件详解
后端
开开心心就好20 分钟前
手机悬屏翻译工具外语游戏漫画APP全覆盖
android·前端·javascript·python·游戏·pdf·html
梦在远山后21 分钟前
Python 中两种 Queue 的区别
python·langchain
分支预测失败22 分钟前
RISC-V 虚拟内存与 MMU 实战:从 Sv39 页表到 Linux 地址空间
后端
步行cgn22 分钟前
@SpringBootTest 详解:Spring Boot 测试的核心注解
后端
对象存储与RustFS27 分钟前
给 RustFS 拆多租户权限:IAM 用户、组与策略的实战
后端·rust·开源
狮子雨恋27 分钟前
anaconda python环境和QT python环境不一致如何解决
开发语言·python·qt
旖旎夜光33 分钟前
【AI入门】大模型介绍全解析:从模型、LLM 到提示词与嵌入
人工智能·笔记·python·学习·ai编程