Flask之请求和响应
Flask中的request请求
- request:flask中代表当前请求的
request 对象
- 作用:在视图函数中取出本次请求数据
- 导入:
from flask import request
- 代码位置:
- 代理类 from flask.app import Request,
- 源码类:from werkzeug.wrappers.Request
- 父类:from werkzeug.wrappers.base_request
常用的属性如下:
属性 | 说明 | 类型 |
---|---|---|
data | 记录请求体的数据,并转换为字符串 只要是通过其他属性无法识别转换的请求体数据 最终都是保留到data属性中 例如:有些公司开发小程序,原生IOS或者安卓,这一类客户端有时候发送过来的数据就不一样是普通的表单,查询字符串或ajax |
bytes类型 |
form | 记录请求中的html表单数据 | MultiDict |
args | 记录请求中的查询字符串,也可以是query_string | MultiDict |
cookies | 记录请求中的cookie信息 | Dict |
headers | 记录请求中的请求头 | EnvironHeaders |
method | 记录请求使用的HTTP方法 | GET/POST |
url | 记录请求的URL地址 | string |
files | 记录请求上传的文件列表 | * |
json | 记录ajax请求的json数据 | json |
获取args参数
获取get参数的数据,也就是url问号后的键值对数据
from flask import Flask, request
app = Flask(__name__)
@app.route('/args')
def args():
"""1.获取查询字符串 """
# request
print(request)
"""
访问路径:
http://127.0.0.1:5000/args?name=pure3417&pwd=123&like=sing&like=running
打印结果:
<Request 'http://127.0.0.1:5000/args?name=pure3417&pwd=123&like=sing&like=running' [GET]>
"""
# 获取原生查询字符串 query_string
print(request.query_string)
"""
访问路径:
http://127.0.0.1:5000/args?name=pure3417&pwd=123&like=sing&like=running
打印结果:
b'name=pure3417&pwd=123&like=sing&like=running'
"""
# 获取查询字符串
print(request.args) # 获取查询字符串 也就是url问号后面的
"""
访问路径:
http://127.0.0.1:5000/args?name=pure3417&pwd=123&like=sing&like=running
打印效果:
ImmutableMultiDict([('name', 'zero'), ('pwd', '123')])
MultiDict内部实现的是OrderDict字典结构
from collections import OrderedDict # 有序字典
"""
# 获取指定参数的值,有两种方式
print(request.args.get('name'))
print(request.args['name']) # 不推荐,获取没有指定的参数会报错
"""
访问路径:
http://127.0.0.1:5000/args?name=pure3417&pwd=123&like=sing&like=running
打印结果:
pure3417
"""
# 获取指定参数的多个值,用于接收表单的多选框值 列表类型
print(request.args.getlist('like'))
"""
访问路径:
http://127.0.0.1:5000/args?name=pure3417&pwd=123&like=sing&like=running
打印结果:
['sing', 'running']
"""
return 'hello flask'
if __name__ == '__main__':
app.run(debug=True)
获取data请求体数据
接受客户端发送过来的原生请求体数据,是request.json,request.form,request.files等无法接收的数据,全部会保留到这里
from flask import Flask, request
import json
app = Flask(__name__)
@app.route("/post", methods=["post", "put", "patch"])
def post():
"""2.获取请求体请求数据"""
"""
请求路径:http://127.0.0.1:5000/post
参数:JSON
{
'username': 'pure3417',
'pwd': '123456'
}
"""
print(request.data) # 打印结果:b'{\n\t"name": "pure3417",\n\t"pwd": "123456"\n}'
data = json.loads(request.data)
print(data) # 结果: {'name': 'pure3417', 'pwd': '123456'} 在flask版本较低中使用
return "post ok"
if __name__ == '__main__':
app.run(debug=True)
获取form表单数据
from flask import Flask, request
import json
app = Flask(__name__)
@app.route("/form", methods=['post'])
def form():
# 接受表单提交的数据
print(request.form) # ImmutableMultiDict([('password', '123456'), ('username', 'pure3417')])
print(request.form.get("username")) # pure3417
return "ok"
if __name__ == '__main__':
app.run(debug=True)
获取files文件
from flask import Flask, request
app = Flask(__name__)
@app.route("/files", methods=['post'])
def files():
# 接收上传,files是一个列表
print(request.files) # ImmutableMultiDict([('avatar', <FileStorage: 'hlw.jpg' ('image/jpeg')>)])
avatar = request.files.get("avatar") # ImmutableMultiDict([('avatar', <FileStorage: 'hlw.jpg' ('image/jpeg')>)])
print(avatar) # <FileStorage: 'hlw.jpg' ('image/jpeg')>
return "ok"
if __name__ == '__main__':
app.run(debug=True)
获取headers请求头
from flask import Flask, request
app = Flask(__name__)
@app.route('/headers', methods=['get', 'post'])
def headers():
# 获取请求头的数据
print(request.headers)
"""
访问链接:
http://127.0.0.1:5000/headers
打印内容:
Host: 127.0.0.1:5000
Connection: keep-alive
Content-Length: 0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
Cache-Control: no-cache
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Postman-Token: 849df90b-812c-9d9e-5bb0-7dc6d8956038
Accept: */*
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Sec-Fetch-Site: none
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
"""
print(request.headers.get('Host')) # 打印内容:127.0.0.1:5000
# 例2:获取自定义的请求头信息
print(request.headers.get('pure'))
"""
参数:在Headers上加键值对: pure 3417
打印内容:3417
"""
return 'header ok'
if __name__ == '__main__':
app.run(debug=True)
获取url地址
from flask import Flask, request
app = Flask(__name__)
@app.route('/urls', methods=['post'])
def url():
# 获取本次请求的URL
print(request.url) # http://127.0.0.1:5000/urls
return 'ok'
if __name__ == '__main__':
app.run(debug=True)
获取method方法
from flask import Flask, request
app = Flask(__name__)
# methods=['get', 'post', 'put', 'delete'] 表示允许访问的方法
@app.route('/method', methods=['get', 'post', 'put', 'delete'])
def method():
# 打印请求方法
print(request.method)
"""
get 的时候打印:
GET
post的时候:
POST
put的时候:
PUT
delete的时候:
DELETE
"""
return 'method ok'
if __name__ == '__main__':
app.run(debug=True)
获取json数据
from flask import Flask, request
app = Flask(__name__)
# methods=['get', 'post', 'put', 'delete'] 表示允许访问的方法
@app.route('/json', methods=['get', 'post', 'put', 'delete'])
def json():
# 接受ajax或其他客户端提交过来的json数据
print(request.json) # {'username': 'pure34q7', 'password': '123'}
return 'json ok'
if __name__ == '__main__':
app.run(debug=True)
Flask中的响应
flask默认支持2种响应方式:
-
数据响应: 默认响应html文本,也可以返回 JSON格式,或其他格式
-
页面响应: 重定向
响应的时候,flask也支持自定义http响应状态码
返回页面响应
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def index():
# [默认支持]响应html文本
return "<h1>hello user</h1>"
# return make_response("<h1>hello user</h1>") # 等同于上面的一段
if __name__ == '__main__':
app.run(debug=True)
返回JSON数据
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def index():
# #也可以响应JSON格式代码
# data = {
# "id":1,
# "uname":"pure3417"
# }
# 支持列表形式的JSON数据
data = [
{"id": 1, "username": "pure3417", "age": 18},
{"id": 2, "username": "pure3417", "age": 17},
{"id": 3, "username": "pure3417", "age": 16},
{"id": 4, "username": "pure3417", "age": 15},
]
# flask中返回json数据,都是flask的jsonify方法返回就可以了.
return jsonify(data)
if __name__ == '__main__':
app.run(debug=True)
响应其他数据格式
from flask import Flask, jsonify, make_response
app = Flask(__name__)
@app.route('/')
def index():
# # 返回图片等其他自定义格式数据
# with open('关注.webp', "rb") as f:
# content = f.read()
# response = make_response(content)
# response.headers["Content-Type"] = "image/jpg" # MIME type 类型
# return response
# 下载文件
with open("关注.webp","rb") as f:
content = f.read()
response = make_response(content)
response.headers["Content-Type"] = "application/zip"
return response
if __name__ == '__main__':
app.run(debug=True)
具体的 MIME type 类型可以查看 MIME 参考手册
重定向
from flask import Flask, redirect
app = Flask(__name__)
@app.route("/")
def user():
# 页面跳转 redirect函数就是response对象的页面跳转的封装
return redirect("http://www.baidu.com")
# # redirect内部完成的事情如下:
# from werkzeug.wrappers import Response
# response = Response()
# response.headers["Location"] = "http://www.baidu.com"
# return response
if __name__ == '__main__':
app.run(debug=True)
重定向到自己写的视图函数
可以直接填写自己 url 路径
也可以使用 url_for
生成指定视图函数所对应的 url,通过redirect
来完成跳转
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route("/")
def index():
"""响应处理"""
# 根据视图名称进行页面跳转
# url_for 根据视图函数名获取对应的uri地址
url = url_for("user")
print(url) # 仅仅是根据参数从app.url_map中提取对应的url地址
return redirect(url)
@app.route("/user")
def user():
return "用户中心"
if __name__ == '__main__':
app.run(debug=True)
重定向到带有参数的路由视图
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route("/")
def index():
"""响应处理"""
# 根据视图名称进行页面跳转
url = url_for("user", user_id=3)
return redirect(url)
@app.route("/user/<user_id>")
def user(user_id):
return f"用户中心,user_id={user_id}"
if __name__ == '__main__':
app.run(debug=True)
自定义响应头和状态码
在 Flask 中,可以很方便的返回自定义状态码,以实现不符合 http 协议的状态码,例如:pure: 3417
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def index():
return '状态码为 666', 400
# 还可以使用make_response创建Response对象,然后通过response对象返回数据
@app.route("/pure")
def index2():
response = make_response("ok")
print(response) # <Response 2 bytes [200 OK]>
response.headers["Company"] = "pure" # 自定义响应头
response.status_code = 201 # 自定义响应状态码
return response
if __name__ == '__main__':
app.run(debug=True)