前面一篇文章记录了前端鉴权相关的内容,这篇笔记主要记录关于请求头相关的内容,包括http的一个请求报文解析,fastapi设置cookie与参数、fastapi设置请求头参数等。

HTTP Request

HTTP 的请求报文分为三个部分 请求行、请求头和请求体:

请求行

请求行有请求方法、请求地址、协议版本三个部分,一般就是通过请求行发送一个请求

请求头

请求头一般就是若干属性,都是键值对,服务器端通过请求头获取客户端的基础信息

请求体

请求体大家都不陌生了,就是客户端发送给服务器的数据。

image-20221128182219550

Cookie参数

和前面的设置路径参数、查询参数一样,可以使用fastapi内的方法来定义cookie参数。

但是在定义cookie参数前,需要有cookie参数才能进行测试,通过上一章我们知道,cookie是服务器响应给前端的,所以需要我们先给前端发送一个cookie。

@app05.get("/stu05/setcookie")
def get_setcookie(response:Response):
    response.set_cookie("cookie1","cookie111111111111")
    response.set_cookie("cookie2","cookie222222222222")
    response.set_cookie("cookie3", "cookie333333333333")
    return {"result":"设置cookie成功"}

这里用fastapi的response方法给前端发送了一个set_cookie,前端收到响应,便有了cookie,具体的操作和详细应用在后面会详细拿一章来说,现在主要是测试接收cookie参数。

image-20221128205354624

然后我们随便访问一个链接,就默认创建的hello world吧!就会发现cookie已经存在了。

image-20221128205524793

定义cookie参数

@app05.get("/stu05/getcookie")
def stu05_read_cookie(
        cookie1:Optional[str] = Cookie(None),
        cookie2:Optional[str] = Cookie(None)
):
    return {"cookie1":cookie1,"cookie2":cookie2} # 定义Cookie参数需要使用Cookie类,否则就是查询参数

有了cookie就能通过fastapi的方法来接收cookie参数了,用Cookie声明一个Cookie参数,然后将接收的cookie参数返回!由于已经有了cookie,所以直接在api文档内测试就能发现已经请求完成了!

image-20221128205846938

Header参数

在此之前,我们简单了解一下header和headers的区别:

header是跟body相对应的,就是请求或应答的头部分,就是多个用CRLF分隔的文本行。
header后面连续两个CRLF,之后的部分就是body,通常GET是没有body的。
headers,就是指头部段落里的多个文本行了。

headers就是header中的内容。

@app05.get("/stu05/getheader")
def stu05_read_header(
        user_agent:Optional[str] = Header(None)
):
    return {"User-agent":user_agent}

和其他参数一样,用fastapi的Header类声明一个Header参数即可,上面的user_agent就是一个Header参数,同样不用Header类声明,也会被解析为查询参数。

image-20221128210116404

自动转换

大多数标准的headers用 "连字符"也就是减号'-' 分隔,如user-agent ,但是这样的变量在Python中是无效的。所以不能在python定义参数的时候用一模一样的写法,就此情况,FastAPI的 Header 会默认把参数名称的字符从下划线 (_) 转换为连字符 (-) 来提取并记录 headers

同时,HTTP headers 是大小写不敏感的,因此可以使用标准Python样式声明它们,也就是可以像通常在Python代码中那样使用 user_agent ,而不需要将首字母大写为 User_Agent 或类似的内容;

当然FastAPI也提供了禁用下划线转换的功能,即在对应参数下设置convert_underscores=False即可,如下,但是一些HTTP代理和服务器不允许使用带有下划线的headers,所以可能会导致接收不到信息的情况,所以默认为True即可;

user_agent:Optional[str] = Header(None,convert_underscores=False)

重复的headers

在实际应用中,完全有可能收到重复的headers。也就是相同的header下某一个参数具有多个值。

针对此情况,直接在类型声明中使用一个list来定义这些情况。

@app05.get("/stu05/getheaders")
def stu05_read_headers(
        paramlist:Optional[List[str]] = Header(None)
):
    return {"paramlist":paramlist}

上面的代码就声明了一个List类型的Header参数,然后通过Postman可以更加直接的展示出来重复的Headers是什么意思,如下:

image-20221128215556195

源码

# -*- coding: utf-8 -*-
# @Time: 2022/11/28 18:27
# @Author: MinChess
# @File: stu05.py
# @Software: PyCharm

from fastapi import APIRouter,Response,Cookie,Header
from pydantic import BaseModel
from typing import Optional,List

app05 = APIRouter()


@app05.get("/stu05/setcookie")
def get_setcookie(response:Response):
    response.set_cookie("cookie1","cookie111111111111")
    response.set_cookie("cookie2","cookie222222222222")
    response.set_cookie("cookie3", "cookie333333333333")
    return {"result":"设置cookie成功"}

@app05.get("/stu05/getcookie")
def stu05_read_cookie(
        cookie1:Optional[str] = Cookie(None),
        cookie2:Optional[str] = Cookie(None)
):
    '''
    :param cookie1:
    :param cookie2:
    :return:
    '''
    return {"cookie1":cookie1,"cookie2":cookie2} # 定义Cookie参数需要使用Cookie类,否则就是查询参数

@app05.get("/stu05/getheader")
def stu05_read_header(
        user_agent:Optional[str] = Header(None)
):
    return {"User-agent":user_agent}

@app05.get("/stu05/getheaders")
def stu05_read_headers(
        paramlist:Optional[List[str]] = Header(None)
):
    return {"paramlist":paramlist}