http包体

2020-01-05  本文已影响0人  温岭夹糕

ABNF范式:https://www.jianshu.com/p/fe82f22f09f6

回顾下ABNF范式对HTTP包体的描述

message-body = *OCTET

OCTET为8位数据

*OCTET为二进制流

HTTP是应用层协议,除了发送数据后,还得告诉上层应用这是什么数据(头部定义)

如何告诉是什么数据,参考了MIME规范

有时候为了节约带宽,在传输过程中还会压缩数据,所以还需要一个Encoding type告诉对方用了什么编码

content := " Content-Type " ":" type "/" subtype *(";" parameter)

type := discrete-type / composite-type discrete-type :="text" / "image" / "audio" / "video" / "application" / extention-tokencomposite-type := "message" / "multipart" / extension-token extension-token :=ietf-token / x-tokensubtype :=extension-token / iana-tokenparameter := attribute "=" value

客户端用 Accept 头告诉服务器希望接收什么样的数据,而服务器用 Content 头告诉客户端实际发送了什么样的数据

请求发送方 响应

Accept-Encoding字段标记的是客户端支持的压缩格式,例如上面说的 gzip、deflate 等,同样也可以用“,”列出多个,服务器可以选择其中一种来压缩数据,实际使用的压缩格式放在响应头字段Content-Encoding

浏览器能接受的压缩方式 响应数据时使用的压缩方式

同理语言:Accept-Language和Content-Language

编码:Accept-Charset和Content-Charset

请求发送方

我们将这些双方消息包体内容约束称为内容协商(还有质量因子q)

HTTP包体的传输方式

包体的传输方式分为两种

1.定长传输

这个很常见,即在发送HTTP消息时已经能够确定包体的长度

其中包体的长度我们在头部Content-Length中指明

Content-Length = 1*DIGIT

DIGIT为10进制

为什么要用10进制表示,因为这需要被我们肉眼所观察到

那么如果两者不一致会出现什么情况?即Content-length和包体实际长度不一致

我们实验测试一下

这里我用php的swoole搭建(需要安装最新swoole扩展)

搭建简单的socket服务器

再来回顾下ABNF对响应的定义

HTTP-message = status-line *(header-field CRLF)CRLF [message-body]

其中CRLF就相当于 \r\n

先改成与实际长度相同

运行程序,分别浏览器访问和curl观察结果

浏览器返回 curl结果

当Content-length<实际长度

只显示5个字节 curl结果

当Content-length>实际长度

浏览器无响应 curl无响应

2.不定长传输

后面不太理解,先记录别人的笔记

使用Transfer-Encoding头部指明使用的Chunk传输方式

含Transfer-Encoding头部后Content-Length头部应被忽略

优点:

基于长连接持续推送动态内容

压缩体积较大的包体时,不必完全压缩完(计算出头部)再发送,可以边发送边压缩

传递必须在包体传输完才能计算出的 Trailer 头部

表单提交时的包体格式

1.在表单提交时我们通常采用POST方法提交

2.在上传文件的表单中,我们通常会对表单的enctype添加选项

application/x-www.form-urlencode

抛出问题:为什么通常会进行以上约定?

关于enctype

enctype属性是在POST方法下对表单内容在请求包体中的提交方式

在w3c中有以下定义

w3c规范

默认地,表单数据会编码为 "application/x-www-form-urlencoded"

1.代码抓包测试

1.1.post和get的区别

post和get区别

GET提交:

在wireshark中表单数据以路由参数(明文)的形式显示

1.1GET抓包

并且是在请求头中

POST:

在谷歌浏览器抓包面板中以包体明文的方式传输(点击view source展开)

1.1POST wireshark抓包 两者以&编码连接

总结:

在POST提交中,采用了application/x-www-form-urlencoded编码方式传输

并且该编码将参数以 & 方式连接

1.2.multipart/form-data的编码方式?

text/plain仅将空格转为+

代码环境

先不上传文件对比

wireshark抓包content-type显示

在Content-type中多了一堆看不懂的玩意儿

RFC中对Content-type为multipart/form-data时的描述

multipart直译为多部份

multipart/form-data即为一个包体中多个资源的表述

即表单中的每一个输入框都为独立的资源描述

RFC描述:

Contetn-Type: multipart/form-data;Boundray

其中Boundray为

boundray := 0*69<bchars> bcharsnospace;

·bchars := bcharsnospace / " "

·bcharsnospace := DIGIT / ALPHA / "" / "(" / ")" / "+" / "-" / "." / "/" /"=" / "?"

boundray不超过70个字符即

boundray不超过70个字符

RFC对multipart包体格式的描述

其中第一个部分(preamble)和最后一个部分(epilogue)一般不使用,使用的时候接收端也会丢弃掉,所以不关注

1*encapsulation表示表单中每一个输入框都为一个encapsulation

wireshark显示4个encapsulation

最后结尾以close-delimiter即再加--

上一篇 下一篇

猜你喜欢

热点阅读