一、核心知识点总结
1、请求数据获取(request 对象)
| 数据来源 | 获取方式 | 说明 |
|---|---|---|
| URL 查询参数 | request.args.get('key') |
?key=value |
| 路径参数 | 视图函数参数 | /user/<int:id> |
| 表单数据 | request.form.get('key') |
application/x-www-form-urlencoded |
| JSON 数据 | request.get_json() |
application/json |
| 文件 | request.files.get('file') |
multipart/form-data |
| 请求头 | request.headers.get('X-Header') |
|
| Cookie | request.cookies.get('key') |
|
| 全部数据 | request.values |
args + form |
2、响应返回方式
| 返回类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | return 'hello' |
自动包装为 200 响应 |
| dict | return {'a': 1} |
自动转为 JSON(Flask 1.1+) |
| 元组 | return data, 201, headers |
(body, status, headers) |
| Response | make_response(...) |
完全控制响应 |
| jsonify | return jsonify(...) |
明确 JSON 响应 |
| redirect | redirect(url_for(...)) |
重定向 |
| 文件 | send_file(...) |
发送文件 |
3、常用状态码
return data, 200 # 成功
return data, 201 # 创建成功
return data, 204 # 无内容(无 body)
return data, 400 # 参数错误
return data, 401 # 未认证
return data, 403 # 无权限
return data, 404 # 资源不存在
return data, 500 # 服务器错误
4、测试命令
# 查询参数
curl "http://127.0.0.1:5000/query?name=Tom&tag=a&tag=b"
# 路径参数
curl "http://127.0.0.1:5000/user/100/post/hello"
# JSON 数据
curl -X POST http://127.0.0.1:5000/json \
-H "Content-Type: application/json" \
-d '{"username": "Tom", "age": 20}'
# 表单数据
curl -X POST http://127.0.0.1:5000/form \
-d "username=Tom&hobby=reading&hobby=music"
# 文件上传
curl -X POST http://127.0.0.1:5000/upload \
-F "file=@/path/to/file.txt"
5、关键区别
request.args vs request.form:前者是 URL 参数,后者是请求体表单
get_json() vs form:前者用于 application/json,后者用于表单编码
get() vs \[\]:get() 无值返回 None(可设默认值),\[\] 无值抛出 400 错误
return dict vs jsonify:Flask 1.1+ 两者等价,旧版本需 jsonify
二、完整示例代码
from flask import Flask, request, jsonify, make_response, render_template
import json
app = Flask(__name__)
# ========== 1. 接收 URL 查询参数 (GET) ==========
@app.route('/query')
def get_query_params():
# 方式1: request.args.get() 单个参数
name = request.args.get('name', 'default_name')
# 方式2: request.args.getlist() 多个同名参数
tags = request.args.getlist('tag')
# 方式3: request.args.to_dict() 转为字典
all_params = request.args.to_dict()
return {
'name': name,
'tags': tags,
'all_params': all_params
}
# ========== 2. 接收路径参数 ==========
@app.route('/user/<int:user_id>/post/<string:post_slug>')
def get_path_params(user_id, post_slug):
return {
'user_id': user_id, # int 类型
'user_id_type': str(type(user_id)),
'post_slug': post_slug # str 类型
}
# ========== 3. 接收 JSON 数据 (POST) ==========
@app.route('/json', methods=['POST'])
def receive_json():
# 获取 JSON 数据
data = request.get_json() # 或 request.json
# 安全获取(如果 body 为空返回 None 而不是报错)
# data = request.get_json(silent=True)
username = data.get('username')
age = data.get('age')
return jsonify({
'received': True,
'username': username,
'age': age
})
# ========== 4. 接收表单数据 (POST) ==========
@app.route('/form', methods=['POST'])
def receive_form():
# 方式1: 单个字段
username = request.form.get('username')
# 方式2: 多个同名字段
hobbies = request.form.getlist('hobby')
# 方式3: 转字典
all_form = request.form.to_dict()
# 方式4: 获取所有数据(表单 + URL参数 + JSON)
# combined = request.values.to_dict()
return {
'username': username,
'hobbies': hobbies,
'all_form': all_form
}
# ========== 5. 接收文件上传 ==========
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files.get('file')
if file is None or file.filename == '':
return {'error': '没有选择文件'}, 400
# 保存文件
file.save(f'./uploads/{file.filename}')
return {
'filename': file.filename,
'content_type': file.content_type
}
# ========== 6. 接收请求头信息 ==========
@app.route('/headers')
def get_headers():
return {
'user_agent': request.headers.get('User-Agent'),
'content_type': request.content_type,
'authorization': request.headers.get('Authorization'),
'all_headers': dict(request.headers)
}
# ========== 7. 不同格式的响应 ==========
# 7.1 返回字符串
@app.route('/resp/string')
def resp_string():
return 'Hello, Flask!'
# 7.2 返回 JSON(dict 自动转 JSON)
@app.route('/resp/json')
def resp_json():
return {'message': 'success', 'code': 0}
# 7.3 返回 JSON(jsonify 更明确)
@app.route('/resp/jsonify')
def resp_jsonify():
return jsonify(message='success', data=[1, 2, 3])
# 7.4 返回 元组:(body, status, headers)
@app.route('/resp/tuple')
def resp_tuple():
return {'error': 'Not Found'}, 404, {'X-Custom-Header': 'value'}
# 7.5 返回自定义响应对象 make_response
@app.route('/resp/custom')
def resp_custom():
resp = make_response({'data': 'hello'})
resp.status_code = 201
resp.headers['X-Custom'] = 'custom-value'
resp.set_cookie('session_id', 'abc123')
return resp
# 7.6 返回 HTML 模板
@app.route('/resp/html')
def resp_html():
return render_template('index.html', title='首页')
# 7.7 返回重定向
from flask import redirect, url_for
@app.route('/resp/redirect')
def resp_redirect():
return redirect(url_for('resp_string'))
# 7.8 返回文件
from flask import send_file, send_from_directory
@app.route('/resp/file')
def resp_file():
# 从目录发送文件
return send_from_directory('./uploads', 'example.txt', as_attachment=True)
# ========== 8. 综合示例:CRUD 接口 ==========
users_db = {}
@app.route('/api/users', methods=['GET'])
def list_users():
return jsonify(list(users_db.values()))
@app.route('/api/users', methods=['POST'])
def create_user():
data = request.get_json()
if not data or 'name' not in data:
return jsonify({'error': 'name 是必填项'}), 400
user_id = len(users_db) + 1
user = {
'id': user_id,
'name': data['name'],
'email': data.get('email', '')
}
users_db[user_id] = user
return jsonify(user), 201
@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
if user_id not in users_db:
return jsonify({'error': '用户不存在'}), 404
data = request.get_json()
users_db[user_id].update(data)
return jsonify(users_db[user_id])
@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
if user_id not in users_db:
return jsonify({'error': '用户不存在'}), 404
del users_db[user_id]
return '', 204
if __name__ == '__main__':
app.run(debug=True)