Flask请求与响应

一、请求方法

1.1 接口常用请求方法

  • Flask框架支持常见的HTTP请求方法,最常用的请求方法为:
请求 说明 备注
GET 获取服务器资源 一般是从服务器中获取资源,存在不安全性,如果有敏感信息,会使用POST
POST 新增服务器资源 主要是将【数据发送到服务器】创建或更新资源,对数据长度没有限制
PUT 更新服务器资源(客户端提供改变后的完整资源) 将【数据发送到服务器】创建或更新资源
DELETE 删除服务器资源 用来删除指定的资源

1.2 GET请求

  • 默认情况下,Flask路由定义的视图函数只支持GET请求。如果需要支持其他请求方法,需要显示地指定methods参数。
from flask import Flask

# 创建Flask应用程序实例
app = Flask(__name__)


# get请求
@app.route("/get")
def get():
    return f"Method is GET."


# methods是一个列表类型,可以添加多种请求方式,如get、post、put、delete...
@app.route("/get_method", methods=["GET"])
def get_method():
    return f"GET method success"


if __name__ == '__main__':
    app.run()

  • 使用Postman检查运行结果。

1.3 POST请求

from flask import Flask

# 创建Flask应用程序实例
app = Flask(__name__)


# post请求
@app.route("/post", methods=["post"])
def post():
    return f"Method is post."


if __name__ == '__main__':
    app.run()


1.4 PUT请求

from flask import Flask

# 创建Flask应用程序实例
app = Flask(__name__)


# post请求
@app.route("/post", methods=["post"])
def post():
    return f"Method is post."


if __name__ == '__main__':
    app.run()


1.5 DELETE请求

from flask import Flask

app = Flask(__name__)


# delete请求
@app.route("/delete", methods=["delete"])
def delete():
    return f"Method is delete."


if __name__ == '__main__':
    app.run()

二、处理请求数据

2.1 request对象

  • 当浏览器访问一个地址时,HTTP协议会向后台传递一个request对象,这个request对象包含请求头、请求参数、以及请求方式。后台可以取到request,然后进行逻辑处理。
  • 在Flask中,可以使用request对象来处理请求数据。request对象提供了访问请求数据的方法和属性。
  • 官方文档

2.2 request的常用属性/方法

属性/方法 说明
args 记录请求中的查询参数
json 记录请求中的 json 数据
files 记录请求上传的文件
form 记录请求中的表单数据
method 记录请求使用的 HTTP 方法
url 记录请求的 URL 地址
host 记录请求的域名
headers 记录请求的头信息

2.2.1 普通请求参数处理

  • 如果一个GET请求在URL中拼接了请求参数,可以使用request.args来获取GET请求中携带的请求参数。
  • request.args是一个字典,可以通过键名来获取参数的值。
from flask import Flask, request

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route("/user")
def get_user():
    # 获取URL中的请求参数
    url_param = request.args
    # 查看获取到的请求参数的类型
    print(type(url_param))
    # 获取请求参数中的username对应的值
    username = url_param.get("username")
    return f"Hello, {username}"


if __name__ == '__main__':
    app.run()


image

  • 查看服务端日志信息,request.args取出值的数据类型为werkzeug.datastructures.structures.ImmutableMultiDict,也是一个可迭代的对象,访问方法和基础的字典类似。
  • 想要获取这个字典中对应的值,可以直接使用get()方法。

2.2.2 JSON请求参数处理

  • 如果是POST或PUT相关的请求,需要带有JSON数据格式,可使用request.json来获取对应的JSON数据。
from flask import Flask, request

# 创建Flask应用程序实例
app = Flask(__name__)

@app.route("/data", methods=["POST"])
def process_data():
    # 获取JSON格式请求体
    data = request.json
    # 查看获取到的请求参数的类型
    print(type(data))
    # 获取请求体中对应字段的值
    name = data.get("name")
    age = data.get("age")
    return f"姓名:{name},年龄:{age}"

if __name__ == '__main__':
    app.run()
  • request.json会解析请求中的JSON数据,并返回一个包含解析后的数据的字典,然后可以根据需要获取特定的字段值。
  • 在Postman中提交JSON格式的请求体,将返回对应字段的值。

2.2.3 表单请求参数处理

  • 如果是POST相关的请求,需要带有form表单数据格式,可以使用request.form来获取POST请求中的表单数据。
  • request.form是一个字典,可以通过键名来获取表单字段的值。
  • 在Postman中提交表单格式的请求体,将返回对应字段的值。

2.2.4 文件请求参数处理

  • 如果页面需要提交一个图片,或上传一个文件到后端服务器,可以使用request.files来获取请求中包含的文件。
  • request.files是一个字典,每个上传的文件都会储存在这个字典里。可以通过file这个key来获取其中的文件对象。
  • 已上传的文件存储在内存或是文件系统中一个临时的位置,它有一个save()方法,允许把文件保存到服务器的文件系统上。
  • 如果想知道上传前文件在客户端的文件名是什么,可以访问filename属性。但这个值是可以伪造的。如果要把文件按客户端提供的文件名存储在服务器上,需要把它传递给Werkzeug提供的secure_filename()函数。这个函数可以用来确保文件名是安全的。
from flask import Flask, request

app = Flask(__name__)


@app.route("/upload/", methods=["POST"])
def upload_file():
    # 获取文件格式的请求体
    file = request.files
    # 查看获取到的请求参数的数据类型
    print(type(file))
    # 获取请求体中对应字段的值
    f = file.get("file")
    return f"File is post!"


if __name__ == '__main__':
    app.run()


2.2.5 其他请求参数处理

三、处理响应信息

3.1 接口响应常见类型

  • 文本型
  • 元组
  • JSON
  • HTML
  • 额外数据

3.1.1 返回文本类型

from flask import Flask

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route("/text/")
def text_res():
    return "这里返回文本类型的数据"


# 运行应用程序
if __name__ == '__main__':
    app.run()
  • 视图函数text_res()直接返回一个字符串,Flask将自动封装成一个纯文本响应并发送给客户端。打开浏览器,就可以看到接口返回的文本内容。
  • 打开浏览器开发者工具Network面板查看这个接口, Response Headers 中的Content-Typetext/html; charset=utf-8

3.2 返回元组类型

  • 元组格式包含3个参数类型,第一个是response对象,第二个是响应状态码,第三个是响应头信息。
  • 也可以只填写2个返回信息,如(response, status)结合,或者(response, headers)结合。
from flask import Flask

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route("/tuple/")
def tuple_res():
    return "你好啊Flask", 200, {"name": "hogwarts"}


# 运行应用程序
if __name__ == '__main__':
    app.run()
  • 打开浏览器开发者工具Network面板查看这个接口, Response Headers 中的Content-Typetext/html; charset=utf-8 ,响应状态码是200,响应头中包含了name字段。

3.3 返回JSON类型

  • 在前后端分离开发的实践中,后端提供的接口响应信息基本都为通用的JSON格式。

  • 返回JSON类型的响应数据有两种方法:

(1)使用jsonify()方法,支持直接传入一个字典,也支持通过关键字传参;
---->直接传入字典

from flask import Flask, jsonify

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route("/json/")
def json_res():
    return jsonify({"status": 200, "name": "hogwarts"})


# 运行应用程序
if __name__ == '__main__':
    app.run()

---->通过关键字传参

from flask import Flask, jsonify

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route('/json/')
def json_res():
    return jsonify(status=1, name="Harry", age=20)


# 运行应用程序
if __name__ == '__main__':
    app.run()

(2)直接返回字典,在Flask 1.1版本之后,直接返回python字典类型时,Flask会调用jsonify()方法。

from flask import Flask

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route("/dict/")
def dict_res():
    return {"status": 500, "name": "Skathy", "gender": "female"}


# 运行应用程序
if __name__ == '__main__':
    app.run()

3.4 返回HTML类型

from flask import Flask, render_template

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route('/html/')
def html_res():
    # 调用render_template方法,传入HTML文件的名称
    # 注意HTML文件必须在templates目录下
    return render_template("demo.html")


# 运行应用程序
if __name__ == '__main__':
    app.run()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Flask返回的HTML</title>
</head>
<body>
    <h2>这是Flask返回的HTML页面</h2>
</body>
</html>

3.5 返回额外数据

from flask import Flask, render_template,make_response

# 创建Flask应用程序实例
app = Flask(__name__)


@app.route('/')
def cookie_res():
    resp = make_response(render_template("demo.html"))
    # 设置cookie
    resp.set_cookie("username", "the username")
    # 设置响应头信息
    resp.headers["hogwarts"] = "Harry"
    return resp


# 运行应用程序
if __name__ == '__main__':
    app.run()