欢迎光临
我们一直在努力

Flask入门教程(七):请求与响应——Web应用的核心数据流

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应用数据流转的核心。

赞(0)
未经允许不得转载:171主机测评 » Flask入门教程(七):请求与响应——Web应用的核心数据流
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址