如何区分请求参数、表单参数、URL参数、Header参数和Cookie参数?一文详解!
- 内容介绍
- 文章标签
- 相关推荐
本文共计1909个文字,预计阅读时间需要8分钟。
最近在处理工作中对 HTTP 请求参数的解析有了进一步的了解,以下是一些简要的笔记:
- HTTP 请求参数通常位于 URL 中,以查询字符串的形式出现,如 `?key1=value1&key2=value2`。- 参数键和值之间使用 `=` 连接,不同参数之间使用 `&` 分隔。- 参数键和值都是字符串类型,但可以进行类型转换。
回顾自己的情况,大体上具备网络和编程基础知识,只需加深对 HTTP 协议的理解即可。
最近在工作中对 localhost:5000/api/hello
- 请求路径后面跟的是 HTTP 的版本,比如这里是
HTTP/1.1
完整的第一行如下:
POST /api/hello HTTP/1.1
第二行的 User-Agent 则用于告诉对方发起请求的客户端是啥,比如咱们用 Postman 发起的请求,Postman 就会自动把这个参数设置为它自己:
User-Agent: PostmanRuntime/7.28.4
第三行的 Accept 用于告诉对方我们希望收到什么类型的数据,这里默认是能接受所有类型的数据:
Accept: */*
第四行就非常值得留意,Postman-Token 是 Postman 自己传的参数,这个我们放到下面讲!
Postman-Token: ddd72e1a-0d63-4bad-a18e-22e38a5de3fc
第五行是请求的主机,网络上的一个服务一般用 ip 加端口作为唯一标识:
Host: 127.0.0.1:5000
第六行指定的是咱们请求发起方可以理解的压缩方式:
Accept-Encoding: gzip, deflate, br
第七行告诉对方处理完当前请求后不要关闭连接:
Connection: keep-alive
第八行告诉对方咱们请求体的内容格式,这个是本文的侧重点啦!比如我们这里指定的是一般浏览器的原生表单格式:
Content-Type: application/x-www-form-urlencoded
好了,下面大家要留意了,第九行的 Content-Length 给出的是请求体的大小。
而请求体,会放在紧跟着的一个空行之后。比如本请求的请求体内容是以 key=value 形式填充的,也就是我们表单参数的内容了:
Content-Length: 23
name=%E9%98%BF%E8%8F%8C
看到这里我们先简单小结一下,想要告诉服务器我们发送的是表单数据,一共需要两步:
- 将
Content-Type设置为application/x-www-form-urlencoded - 在请求体中按照
key=value的形式填写请求参数
框架会帮助我们从 url 中的 ? 后面开始截取,然后把 name=ajun 这些参数存放到 args 里。
切换一下,假设我们是云你好服务提供者,我们希望用户通过表单参数的形式使用云你好服务,我们只要把获取 name 参数的方式改成从表单参数里获取就可以了,flask 在 request.form 里封装了表单参数(关于框架是怎么在数行 http 请求中封装参数的,大家可以看自己使用的框架的具体逻辑,估计区别不大,只是存在一些语言特性上的差异):
@app.post("/api/hello")
def hello():
# 看用户是否传递了参数 name
name = request.form.get("name", "")
# 如果传了参数就向目标对象打招呼,输出 Hello XXX,否则输出 Hello World
return f"Hello {name}" if name else "Hello World"
思考:我们可以在 http 协议中传递什么参数?
最后,我们解释本文的标题,其实想要明白各种参数之间的区别,我们可以换一个角度思考:
咱们可以在一份 http 报文的哪些位置传递参数?
接下来回顾一下一个 http 请求的内容:
POST /api/hello HTTP/1.1
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: fbf75035-a647-46dc-adc0-333751a9399e
Host: 127.0.0.1:5000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
name=%E9%98%BF%E8%8F%8C
大家看,咱们的 http 报文,也就是基于传输层之上的应用层报文,大概就长上面这样。
我们考虑两种情况,第一种情况,我们基于别人已经开发好的脚手架开发 http 服务器。
由于框架会基于 http 协议进行解析,所以框架会帮助我们解析好请求 url,各种 Header 头(比如:Cookie 等),以及具体的响应内容都帮我们封装解析好了(比如按照 key=value 的方式去读取请求体)。
那当我们开发服务端的时候,就可以指定从 url、header、响应体中获取参数了,比如:
- url 参数:指的就是 url 中 ? 后面携带的 key value 形式参数
- header 参数:指的就是各个 header 头,我们甚至可以自定义 header,比如 Postman-Token 就是 postman 这个软件自己携带的,我们服务端如果需要的话是可以指定获取这个参数的
- Cookie 参数:其实就是名字为 Cookie 的请求头
- 表单参数:指的就是 Content-Type 为 application/x-www-form-urlencoded 下请求体的内容,如果我们的表单需要传文件,还会有其他的 Content-Type
- json 参数:指的就是 Content-Type 为 application/json 下请求体的内容(当然服务端可以不根据 Content-Type 直接解析请求体,但按照协议的规范工程项目或许会更好维护)
综上所述,请求参数就是对上面各种类型的参数的一个总称了。
大家会发现,不管什么 url 参数、header 参数、Cookie 参数、表单参数,其实就是换着法儿,按照一定的格式把数据放到应用层报文中。关键在于我们的服务端程序和客户端程序按照一种什么样的约定去传递和获取这些参数。这就是协议吧~
还有另一种情况,当然这只是开玩笑了,比如以后哪位大佬或者哪家企业定义了一种新的数据传输标准,推广至全球,比如叫 hppt 协议,这样是完全可以自己给各种形式参数下定义取名字的。这可能就是为啥我们说一流的企业、大佬制定标准,接下来的围绕标准研发技术,进而是基于技术卖产品,最后是围绕产品提供服务了。
一旦标准制定了,整个行业都围绕这个标准转了,而且感觉影响会越来越深远......
讲解参考链接
本文共计1909个文字,预计阅读时间需要8分钟。
最近在处理工作中对 HTTP 请求参数的解析有了进一步的了解,以下是一些简要的笔记:
- HTTP 请求参数通常位于 URL 中,以查询字符串的形式出现,如 `?key1=value1&key2=value2`。- 参数键和值之间使用 `=` 连接,不同参数之间使用 `&` 分隔。- 参数键和值都是字符串类型,但可以进行类型转换。
回顾自己的情况,大体上具备网络和编程基础知识,只需加深对 HTTP 协议的理解即可。
最近在工作中对 localhost:5000/api/hello
- 请求路径后面跟的是 HTTP 的版本,比如这里是
HTTP/1.1
完整的第一行如下:
POST /api/hello HTTP/1.1
第二行的 User-Agent 则用于告诉对方发起请求的客户端是啥,比如咱们用 Postman 发起的请求,Postman 就会自动把这个参数设置为它自己:
User-Agent: PostmanRuntime/7.28.4
第三行的 Accept 用于告诉对方我们希望收到什么类型的数据,这里默认是能接受所有类型的数据:
Accept: */*
第四行就非常值得留意,Postman-Token 是 Postman 自己传的参数,这个我们放到下面讲!
Postman-Token: ddd72e1a-0d63-4bad-a18e-22e38a5de3fc
第五行是请求的主机,网络上的一个服务一般用 ip 加端口作为唯一标识:
Host: 127.0.0.1:5000
第六行指定的是咱们请求发起方可以理解的压缩方式:
Accept-Encoding: gzip, deflate, br
第七行告诉对方处理完当前请求后不要关闭连接:
Connection: keep-alive
第八行告诉对方咱们请求体的内容格式,这个是本文的侧重点啦!比如我们这里指定的是一般浏览器的原生表单格式:
Content-Type: application/x-www-form-urlencoded
好了,下面大家要留意了,第九行的 Content-Length 给出的是请求体的大小。
而请求体,会放在紧跟着的一个空行之后。比如本请求的请求体内容是以 key=value 形式填充的,也就是我们表单参数的内容了:
Content-Length: 23
name=%E9%98%BF%E8%8F%8C
看到这里我们先简单小结一下,想要告诉服务器我们发送的是表单数据,一共需要两步:
- 将
Content-Type设置为application/x-www-form-urlencoded - 在请求体中按照
key=value的形式填写请求参数
框架会帮助我们从 url 中的 ? 后面开始截取,然后把 name=ajun 这些参数存放到 args 里。
切换一下,假设我们是云你好服务提供者,我们希望用户通过表单参数的形式使用云你好服务,我们只要把获取 name 参数的方式改成从表单参数里获取就可以了,flask 在 request.form 里封装了表单参数(关于框架是怎么在数行 http 请求中封装参数的,大家可以看自己使用的框架的具体逻辑,估计区别不大,只是存在一些语言特性上的差异):
@app.post("/api/hello")
def hello():
# 看用户是否传递了参数 name
name = request.form.get("name", "")
# 如果传了参数就向目标对象打招呼,输出 Hello XXX,否则输出 Hello World
return f"Hello {name}" if name else "Hello World"
思考:我们可以在 http 协议中传递什么参数?
最后,我们解释本文的标题,其实想要明白各种参数之间的区别,我们可以换一个角度思考:
咱们可以在一份 http 报文的哪些位置传递参数?
接下来回顾一下一个 http 请求的内容:
POST /api/hello HTTP/1.1
User-Agent: PostmanRuntime/7.28.4
Accept: */*
Postman-Token: fbf75035-a647-46dc-adc0-333751a9399e
Host: 127.0.0.1:5000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
name=%E9%98%BF%E8%8F%8C
大家看,咱们的 http 报文,也就是基于传输层之上的应用层报文,大概就长上面这样。
我们考虑两种情况,第一种情况,我们基于别人已经开发好的脚手架开发 http 服务器。
由于框架会基于 http 协议进行解析,所以框架会帮助我们解析好请求 url,各种 Header 头(比如:Cookie 等),以及具体的响应内容都帮我们封装解析好了(比如按照 key=value 的方式去读取请求体)。
那当我们开发服务端的时候,就可以指定从 url、header、响应体中获取参数了,比如:
- url 参数:指的就是 url 中 ? 后面携带的 key value 形式参数
- header 参数:指的就是各个 header 头,我们甚至可以自定义 header,比如 Postman-Token 就是 postman 这个软件自己携带的,我们服务端如果需要的话是可以指定获取这个参数的
- Cookie 参数:其实就是名字为 Cookie 的请求头
- 表单参数:指的就是 Content-Type 为 application/x-www-form-urlencoded 下请求体的内容,如果我们的表单需要传文件,还会有其他的 Content-Type
- json 参数:指的就是 Content-Type 为 application/json 下请求体的内容(当然服务端可以不根据 Content-Type 直接解析请求体,但按照协议的规范工程项目或许会更好维护)
综上所述,请求参数就是对上面各种类型的参数的一个总称了。
大家会发现,不管什么 url 参数、header 参数、Cookie 参数、表单参数,其实就是换着法儿,按照一定的格式把数据放到应用层报文中。关键在于我们的服务端程序和客户端程序按照一种什么样的约定去传递和获取这些参数。这就是协议吧~
还有另一种情况,当然这只是开玩笑了,比如以后哪位大佬或者哪家企业定义了一种新的数据传输标准,推广至全球,比如叫 hppt 协议,这样是完全可以自己给各种形式参数下定义取名字的。这可能就是为啥我们说一流的企业、大佬制定标准,接下来的围绕标准研发技术,进而是基于技术卖产品,最后是围绕产品提供服务了。
一旦标准制定了,整个行业都围绕这个标准转了,而且感觉影响会越来越深远......
讲解参考链接

