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即再加--
网友评论