Flask 的 request 对象

浏览器访问服务端时,向服务端发送请求。Flask 程序使用 request 对象描述请求信息,本小节介绍 request 对象的概念,以及它的重要属性:form 和 args,并对属性的使用给出一个例子。

1. 简介

浏览器访问服务端,需要将相应的数据发送给服务端,可能有如下场景:

  1. 通过 URL 参数进行查询,浏览器需要将查询参数发送给服务端
  2. 提交表单 form 进行查询,浏览器需要将表单 form 中的字段发送给服务端
  3. 上传文件,浏览器需要将文件发送给服务端

服务端收到将客户端发送的数据后,封装形成一个请求对象,在 Flask 中,请求对象是一个模块变量 flask.request,它包含了如下常用属性:

属性 说明
method 当前的请求方法
form 表单参数及其值的字典对象
args 查询字符串的字典对象
values 包含所有数据的字典对象
json 如果 mimetype 是 application/json,这个参数将会解析 json 数据,如果不是则返回 None
headers http 协议头部
cookies cookie 名称和值的字典对象
files 与上传文件有关的数据

假设 URL 等于 http://localhost/query?userId=123,request 对象中与 URL 参数相关的属性如下:

属性 说明
url http://localhost/query?userId=123
base_url http://localhost/query
host localhost
host_url http://localhost/
path /query
full_path /query?userId=123

2. 获取 URL 相关参数

本节编写一个 Flask 程序 request-url.py,打印 request 中和 URL 相关的属性:

from flask import Flask
from flask import request
app = Flask(__name__)

def echo(key, value):
    print('%-10s = %s' % (key, value))

@app.route('/query')
def query():
    echo('url', request.url)
    echo('base_url', request.base_url)    
    echo('host', request.host)
    echo('host_url', request.host_url)
    echo('path', request.path)
    echo('full_path', request.full_path)
    return 'hello'

if __name__ == '__main__':
    app.run(port = 80)
url        = http://localhost/query?userId=123
base_url   = http://localhost/query
host       = localhost
host_url   = http://localhost/
path       = /query
full_path  = /query?userId=123

3. 解析查询参数

request.args 保存了 URL 中的查询参数,下面编写一个例子 request-args.py 解析 URL 中的查询参数:

from flask import Flask, request
app = Flask(__name__)

@app.route('/query')
def query():
    print('name =', request.args['name'])
    print('age =', request.args['age'])
    return 'hello'

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

在第 4 行,编写路径 /query 对应的处理函数 query(),打印查询参数 name 和 age 的值。在浏览器中输入 URL:http://localhost:5000/query?name=zhangsan&age=13 ,查询字符串为 name=zhangsan&age=13,包含有两个查询参数 name 和 age,Flask 程序在终端输出如下:

name = zhangsan
age = 13

4. 解析表单参数

request.form 保存了表单参数,下面编写一个例子 request-form.py 解析表单参数:

from flask import Flask, request
app = Flask(__name__)

@app.route('/')
def root():
    file = open('form.html', encoding = 'utf-8')
    return file.read()

@app.route('/addUser', methods = ['POST'])
def check_login():
    name = request.form['name']
    age = request.form['age']
    print('name = %s' % name)
    print('age = %s' % age)
    return 'addUser OK'

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

在第 4 行,编写路径 / 的处理函数 root(),它读取文件 form.html,将内容返回给浏览器。在第 9 行,编写路径 /addUser 的处理函数 addUser(),打印 request.form 中的参数 name 和 age。

路径 / 返回 form.html,内容如下:

<html>
<body>
  <form action="/addUser" method="POST">
    <p><input type="text" name="name"/></p>
    <p><input type="text" name="age"/></p>
    <p><input type="submit" value="submit"/></p>
  </form>
</body>  
</html>

form.html 中包含一个表单,action 为 /addUser,method 为 POST,表单中包含有两个字段 name 和 age。访问 localhost:5000 时,浏览器显示如下:

图片描述

点击提交,浏览器将请求 /addUser 发送给服务端,服务端在终端打印输出:

name = zhangsan
age = 50

5. 解析 json 数据

编写web api,在写 post 请求接口时,通常将接口参数以 json 格式发送给服务端,request.json 保存了请求中的 json 数据,下面编写一个例子 request-json.py 解析 json 数据:

from flask import Flask, request
app = Flask(__name__)

@app.route('/')
def root():
    file = open('api.html', encoding = 'utf-8')
    return file.read()

@app.route('/api/addUser', methods = ['POST'])
def addUser():
    json = request.json
    print('JSON', json)
    print('name = %s' % json['name'])
    print('age = %s' % json['age'])
    return 'addUser OK'

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

在第 4 行,编写路径 / 的处理函数 root(),它读取文件 api.html,将内容返回给浏览器。在第 9 行,编写路径 /api/addUser 的处理函数 addUser(),打印 request.json 中的参数 name 和 age,返回给浏览器 ‘addUser OK’。客户端使用 POST 方法提交请求 /api/addUser,在 Flask 中,需要指明 methods 为 ‘POST’。

路径 / 返回 api.html,api.html 通过 ajax 调用服务端的 /api/addUser,内容如下:

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.js"></script>
<h1 id='result'>result</h1>
<script>
var data = JSON.stringify({'name':'zhangsan', 'age':'20'});
$.ajax({
    url: '/api/addUser',
    type: 'post',
    contentType:'application/json',
    data: data,
   success: function(data) {
        $("#result").html(data);
    },
    error: function(e) {
        alert('ERROR')
    }
});
</script>

在第 2 行,定义 id 为 result 的标签,用于显示调用结果;在第 4 行,设定 /api/addUser 的接口参数: name 和 age;在第 5 行,通过 jquery.ajax 调用服务端的 /api/addUser。请求调用成功时,回调 success 函数,将结果显示在 id 为 result 的标签中,如下所示:

图片描述

6. 源代码下载

7. 小结

本小节讲解了 request 对象的常见属性,使用思维导图总结如下:

图片描述