Flask 请求数据获取方法详解

一、工作原理

在 Flask 中,所有客户端请求的数据都通过全局的 request 对象访问。该对象是 请求上下文 的一部分,仅在请求处理期间存在。Flask 在收到请求时自动创建 request 对象,并根据请求类型(如 GET、POST)和内容类型(如表单、JSON)解析数据,将不同来源的数据封装到对应的属性中(如 argsformjson)。

二、常用方法
  1. 查询参数(URL参数)

    使用 request.args(类型:ImmutableMultiDict)获取 URL 中的查询参数。

    python 复制代码
    name = request.args.get('name')  # 获取单个参数
    all_args = request.args.to_dict()  # 转为字典
  2. 表单数据

    针对 application/x-www-form-urlencodedmultipart/form-data 类型的 POST 请求,使用 request.form

    python 复制代码
    username = request.form.get('username')
  3. JSON 数据

    当请求的 Content-Typeapplication/json 时,使用 request.json 直接获取解析后的字典。

    python 复制代码
    data = request.json
  4. 文件上传

    通过 request.files 获取上传的文件(类型:FileStorage)。

    python 复制代码
    file = request.files.get('file')
    if file:
        file.save('uploaded_file.txt')
  5. 原始数据

    使用 request.data 获取未经处理的原始字节数据(如非表单、非JSON的请求体)。

  6. 请求头与Cookies

    python 复制代码
    user_agent = request.headers.get('User-Agent')
    user_token = request.cookies.get('token')
三、高级用法
  1. 处理多值参数

    当参数有多个值时(如多选框),使用 getlist

    python 复制代码
    selected_ids = request.form.getlist('ids')
  2. 强制解析JSON

    即使 Content-Type 不是 application/json,也可强制解析:

    python 复制代码
    data = request.get_json(force=True)
  3. 流式处理大文件

    使用 request.stream 逐块读取数据,避免内存溢出:

    python 复制代码
    @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'
  4. 混合数据(表单+JSON)

    使用 request.values 合并查询参数和表单数据(不推荐混用,需谨慎处理逻辑)。

四、完整示例
python 复制代码
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api', methods=['GET', 'POST'])
def handle_request():
    # 获取查询参数
    query_param = request.args.get('q')
    
    # 根据不同请求类型处理数据
    if request.method == 'POST':
        # 处理表单数据
        username = request.form.get('username')
        
        # 处理JSON数据
        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)
五、注意事项
  1. 请求方法影响数据获取

    • GET 请求只有 args,无 formfiles
    • POST 需根据 Content-Type 选择正确的属性(如 formjson)。
  2. 处理缺失数据

    使用 .get('key') 而非 ['key'] 避免 KeyError,可指定默认值:

    python 复制代码
    value = request.form.get('key', 'default')
  3. JSON解析安全

    • 使用 request.get_json(silent=True) 避免解析失败抛出异常。
    • 使用 force=True 时需注意客户端可能发送非法数据。
  4. 文件上传安全

    • 限制文件类型和大小(通过 MAX_CONTENT_LENGTH 配置)。
    • 验证文件名,避免路径遍历漏洞。
六、扩展知识
  1. 请求钩子预处理

    使用 @app.before_request 在请求处理前统一验证或预处理数据:

    python 复制代码
    @app.before_request
    def check_auth():
        if not request.endpoint == 'login' and not validate_token(request.headers.get('Token')):
            return jsonify({"error": "Unauthorized"}), 401
  2. 第三方库扩展

    • Flask-RESTful:构建 REST API,自动解析请求数据。
    • Flask-WTF:集成 WTForms,处理表单验证和CSRF保护。
  3. 性能优化

    • 对于大文件上传,使用流式处理或分块传输。
    • 启用 gzip 压缩减少数据传输量。
  4. 测试请求

    使用 Flask 测试客户端模拟请求:

    python 复制代码
    with app.test_client() as client:
        response = client.post('/api', data={'username': 'test'}, headers={'Content-Type': 'multipart/form-data'})
        assert response.status_code == 200

七、错误处理与调试技巧
1. 优雅处理数据解析错误

在解析客户端数据时,可能会遇到格式错误或非法内容,需合理捕获异常:

python 复制代码
@app.route('/parse-json', methods=['POST'])
def parse_json():
    try:
        data = request.get_json()
        if data is None:
            raise ValueError("Invalid JSON")
        # 处理数据...
    except ValueError as e:
        return jsonify({"error": str(e)}), 400

关键点

  • 使用 silent=True 时,即使解析失败也不会抛出异常,但需手动检查 data 是否为 None
  • 针对文件上传错误,可检查 request.files 是否存在且文件对象有效。

2. 调试请求数据的实用方法

在开发过程中,快速查看原始请求数据有助于定位问题:

python 复制代码
@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:模拟复杂请求(如 multipart/form-data 或自定义 headers)。

  • curl 命令 :快速测试 API 接口:

    bash 复制代码
    curl -X POST http://localhost:5000/api -H "Content-Type: application/json" -d '{"key": "value"}'

八、安全加固策略
1. 防范常见攻击
  • CSRF 保护 :使用 Flask-WTF 扩展自动生成和验证 CSRF Token:

    python 复制代码
    from flask_wtf.csrf import CSRFProtect
    csrf = CSRFProtect(app)

    在表单中添加隐藏字段:

    html 复制代码
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
  • SQL 注入防护:始终使用 ORM(如 SQLAlchemy)或参数化查询,避免拼接 SQL 字符串。

  • XSS 防护:对用户输入的内容进行转义(Flask 模板默认自动转义)。


2. 文件上传安全实践
  • 限制文件扩展名

    python 复制代码
    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 处理文件名:

    python 复制代码
    from werkzeug.utils import secure_filename
    safe_filename = secure_filename(uploaded_file.filename)
    uploaded_file.save(f'uploads/{safe_filename}')

九、异步与性能优化
1. 异步处理大请求

使用 async/await 处理耗时操作(需 Flask 2.0+ 支持异步视图):

python 复制代码
@app.route('/async-upload', methods=['POST'])
async def async_upload():
    data = await request.get_data()
    # 异步处理数据(如写入数据库)
    return "Processing completed"

适用场景

  • 大文件上传后的后台处理(如视频转码)。
  • 高并发下的非阻塞 IO 操作。

2. 性能调优建议
  • 配置请求体大小限制

    python 复制代码
    app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024  # 限制为100MB
  • 启用压缩:通过 Nginx 或 GzipMiddleware 压缩响应数据:

    python 复制代码
    from flask_compress import Compress
    Compress(app)

十、与其他技术栈集成
1. 结合前端框架处理数据
  • React/Vue 表单提交 :确保前端 Content-Type 与后端匹配:

    javascript 复制代码
    // 使用FormData处理文件上传
    const formData = new FormData();
    formData.append('file', fileInput.files[0]);
    fetch('/api/upload', { method: 'POST', body: formData });
  • AJAX 请求处理 :Flask 自动解析 application/json,前端需明确设置 headers:

    javascript 复制代码
    fetch('/api/data', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ key: 'value' })
    });

2. 扩展数据格式支持(如 XML)

若需解析 XML 请求,可自定义解析逻辑:

python 复制代码
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})

十一、实战案例:构建RESTful API
1. 用户注册接口

处理混合数据(JSON + 文件头像上传):

python 复制代码
@app.route('/register', methods=['POST'])
def register():
    # 解析JSON数据
    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)}')
    
    # 保存用户到数据库(伪代码)
    save_user(username)
    
    return jsonify({"status": "success"})

2. 分页查询接口

结合查询参数与数据过滤:

python 复制代码
@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
    })

十二、总结

Flask 的请求数据获取机制兼顾灵活性与简洁性,开发者需根据实际场景选择合适的方法:

  • 基础场景 :直接使用 request.argsrequest.formrequest.json
  • 复杂场景:结合流式处理、异步操作或第三方库扩展功能。
  • 安全优先:始终验证输入、限制资源、防范常见攻击。

通过合理设计数据流和错误处理机制,可以构建出高效、健壮的 Web 应用。

相关推荐
ss27320 分钟前
基于Springboot + vue + 爬虫实现的高考志愿智能推荐系统
spring boot·后端·高考
PXM的算法星球37 分钟前
【软件工程】面向对象编程(OOP)概念详解
java·python·软件工程
专注API从业者1 小时前
《Go 语言高并发爬虫开发:淘宝商品 API 实时采集与 ETL 数据处理管道》
开发语言·后端·爬虫·golang
Humbunklung1 小时前
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRectF)
笔记·python·学习·pyqt
Asthenia04121 小时前
Netty writeAndFlush与Pipeline深入分析
后端
蹦蹦跳跳真可爱5891 小时前
Python----深度学习(基于DNN的吃鸡预测)
python·深度学习·dnn
欧先生^_^2 小时前
Scala语法基础
开发语言·后端·scala
JJ1M82 小时前
Git技巧:Git Hook,自动触发,含实战分享
git·python·自动化
拓端研究室TRL2 小时前
PyMC+AI提示词贝叶斯项目反应IRT理论Rasch分析篮球比赛官方数据:球员能力与位置层级结构研究
大数据·人工智能·python·算法·机器学习
GetcharZp3 小时前
xterm.js 终端神器到底有多强?用了才知道!
前端·后端·go