1. 请求对象------request
Flask通过全局代理对象request提供所有请求信息。虽然它是"全局"对象,但Flask内部通过线程隔离机制确保每个请求获取的是自己的数据,不会互相干扰。
from flask import Flask, request app = Flask(__name__) @app.route("/debug") def debug(): return f""" <h1>请求调试信息</h1> <ul> <li>方法:{request.method}</li> <li>路径:{request.path}</li> <li>完整 URL:{request.url}</li> <li>主机:{request.host}</li> <li>客户端 IP:{request.remote_addr}</li> <li>User-Agent:{request.headers.get('User-Agent')}</li> </ul> """
访问 http://127.0.0.1:5000/debug?foo=bar 即可看到请求的详细信息。
2. 获取查询参数------request.args
URL中?后面的参数称为查询参数(Query String) ,使用request.args读取,它类似于一个字典。
@app.route("/search") def search(): keyword = request.args.get("keyword", "") page = request.args.get("page", "1") return f""" <h1>搜索结果</h1> <p>关键词:{keyword}</p> <p>页码:{page}</p> """
| 测试URL | 结果 |
|---|---|
/search?keyword=flask&page=2 |
关键词:flask,页码:2 |
/search?keyword=RUNOOB |
关键词:RUNOOB,页码:1(默认值) |
💡 推荐使用
.get()方法 :request.args.get("key")在key不存在时返回None(或指定的默认值),而直接使用request.args["key"]在key不存在时会抛出KeyError,导致返回400错误页面。
3. 获取表单数据------request.form
处理POST请求提交的表单数据,使用request.form:
@app.route("/register", methods=["GET", "POST"]) def register(): if request.method == "POST": username = request.form.get("username", "") password = request.form.get("password", "") if not username or not password: return "<h1>错误</h1><p>用户名和密码不能为空</p>", 400 return f"<h1>注册成功</h1><p>欢迎 {username} 加入 RUNOOB!</p>" # GET请求时显示注册表单 return """ <h1>注册</h1> <form method="post"> <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="password" name="password"></p> <p><input type="submit" value="注册"></p> </form> """
⚠️ 注意 :表单必须设置
method="post",否则数据会通过URL查询字符串发送(GET方式),敏感信息会暴露在URL中。
4. 获取JSON数据------request.json
现代Web开发中,JSON是最常见的数据格式。当客户端发送Content-Type: application/json的请求时,使用request.json获取解析后的数据:
@app.post("/api/user") def create_user(): data = request.json name = data.get("name", "未知") email = data.get("email", "未提供") return { "message": "用户创建成功", "name": name, "email": email }
用curl测试:
$ curl -X POST http://127.0.0.1:5000/api/user \ -H "Content-Type: application/json" \ -d '{"name": "runoob", "email": "test@runoob.com"}'
{ "message": "用户创建成功", "name": "runoob", "email": "test@runoob.com" }
5. 文件上传------request.files
处理上传的文件使用request.files,配合Werkzeug提供的secure_filename()确保文件名安全:
import os from werkzeug.utils import secure_filename UPLOAD_DIR = "uploads" @app.route("/upload", methods=["GET", "POST"]) def upload_file(): if request.method == "POST": if "file" not in request.files: return "未选择文件", 400 file = request.files["file"] if file.filename == "": return "文件名为空", 400 filename = secure_filename(file.filename) os.makedirs(UPLOAD_DIR, exist_ok=True) file.save(os.path.join(UPLOAD_DIR, filename)) return f"文件 {filename} 上传成功" return """ <h1>上传文件</h1> <form method="post" enctype="multipart/form-data"> <p><input type="file" name="file"></p> <p><input type="submit" value="上传"></p> </form> """
| 关键点 | 说明 |
|---|---|
secure_filename() |
过滤路径遍历等危险字符,如../../etc/passwd会被处理为etc_passwd |
enctype="multipart/form-data" |
表单包含文件上传时必须设置此属性 |
os.makedirs(..., exist_ok=True) |
确保上传目录存在,exist_ok=True防止目录已存在时报错 |
6. 响应类型完全指南
视图函数可以返回多种类型的数据,Flask会自动将它们转换为合适的HTTP响应。
返回字符串
返回的字符串作为HTML响应体,状态码默认200,Content-Type为text/html。
@app.route("/hello") def hello(): return "<h1>Hello, World!</h1>"
返回字典或列表(JSON)
自动调用jsonify()转换为JSON响应,Content-Type为application/json。
@app.get("/api/posts") def get_posts(): return { "status": "ok", "data": [ {"id": 1, "title": "Flask 入门教程"}, {"id": 2, "title": "RESTful API 设计"}, ] } @app.get("/api/tags") def get_tags(): return ["Python", "Flask", "Web 开发"]
返回元组------控制状态码和响应头
元组有三种组合形式:
# 形式1:(body, status_code) @app.get("/not-found") def not_found(): return "<h1>页面不存在</h1>", 404 # 形式2:(body, headers_dict) @app.get("/custom-header") def custom_header(): return "OK", {"X-Custom-Header": "runoob"} # 形式3:(body, status_code, headers_dict) @app.post("/api/login") def api_login(): return {"token": "abc123"}, 201, {"X-RateLimit": "100"}
重定向------redirect()
使用redirect()函数将用户引导到另一个URL:
from flask import redirect, url_for @app.route("/") def index(): return redirect(url_for("login")) @app.route("/old-page") def old_page(): # 永久迁移使用301状态码 return redirect(url_for("new_page"), code=301) @app.route("/new-page") def new_page(): return "<h1>这是新页面</h1>"
| 状态码 | 含义 | 适用场景 |
|---|---|---|
| 302(默认) | Found | 临时重定向 |
| 303 | See Other | 表单提交后重定向(PRG模式) |
| 301 | Moved Permanently | 永久迁移 |
终止请求------abort()
使用abort()立即终止当前请求并返回HTTP错误:
from flask import abort @app.route("/post/<int:post_id>") def view_post(post_id): if post_id < 1 or post_id > 100: abort(404) return f"<h1>文章 #{post_id}</h1>" @app.route("/admin") def admin(): abort(403, description="你没有权限访问此页面")
make_response------手动控制响应
当需要手动设置Cookie或自定义响应头时,使用make_response():
from flask import make_response @app.route("/set-cookie") def set_cookie(): resp = make_response("<h1>Cookie已设置</h1>") resp.set_cookie("theme", "dark", max_age=60*60*24) # 有效期24小时 resp.headers["X-Powered-By"] = "RUNOOB-Flask" return resp
7. request常用属性速查表
| 属性 | 类型 | 说明 | 示例值 |
|---|---|---|---|
request.method |
str |
HTTP请求方法 | "GET", "POST" |
request.path |
str |
URL路径(不含域名) | "/search" |
request.url |
str |
完整URL | "http://127.0.0.1:5000/search?q=flask" |
request.args |
MultiDict |
URL查询参数 | ?keyword=flask&page=1 |
request.form |
MultiDict |
POST表单数据 | username=admin |
request.json |
dict或None |
JSON请求体(已解析) | {"name": "runoob"} |
request.files |
FileMultiDict |
上传的文件 | request.files["avatar"] |
request.headers |
Headers |
请求头 | request.headers.get("User-Agent") |
request.cookies |
dict |
客户端发来的Cookie | request.cookies.get("theme") |
request.remote_addr |
str |
客户端IP地址 | "127.0.0.1" |
8. 响应类型速查表
| 返回类型 | 示例 | 自动转换结果 |
|---|---|---|
str |
return "<h1>Hello</h1>" |
HTML响应,200 OK |
dict |
return {"key": "value"} |
JSON响应,200 OK |
list |
return ["a", "b"] |
JSON响应,200 OK |
tuple |
return "body", 404 |
自定义状态码 |
tuple |
return "body", {"X-Header": "v"} |
自定义响应头 |
tuple |
return "body", 404, {"X-Header": "v"} |
自定义状态码+响应头 |
Response |
return make_response("body") |
完全控制的响应对象 |
redirect() |
return redirect("/login") |
302重定向 |
abort() |
abort(404) |
错误响应 |
小结
本章全面讲解了Flask的请求与响应机制。请求方面,通过request.args读取URL查询参数,request.form读取POST表单数据,request.json解析JSON请求体,request.files处理文件上传,配合secure_filename()确保安全。响应方面,视图函数可返回字符串(HTML)、字典/列表(JSON)、元组(自定义状态码/响应头),还可以通过redirect()实现重定向、abort()终止请求返回错误、make_response()精细控制响应对象。这些知识构成了Flask Web应用数据流转的核心。