HTTP学习笔记
HTTP 0.9
- HTTP问世之初还未被作为标准,在正式列为标准之前的版本被称为0.9。
- request只有GET命令后跟资源路径;
- response仅包含文件内容本身;
- 发生错误时通过传递回一个包含错误信息的HTML文件。
HTTP 1.0
- request命令后增加版本号;
- response第一行增加状态行;
- request和response新增header的概念;
- header中包含content-type表示文件类型和content-encoding表示编码格式;
- 引入POST和HEAD命令;
- 支持长连接,但默认是短连接;
- 缺点:
- 队头阻塞(浏览器限制单个域名并行TCP连接数通常为4个,同一连接中的请求是串行进行的,所以前面的会阻塞后面的。);
- 默认短连接(每次请求都要重建TCP连接,发送完后关闭连接。);
- 仅定义16种状态码;
HTTP 1.1
- 目前的主流版本,发布后的近十年都没有更新版本;
- keep-active(长连接):TCP连接默认不关闭,可以被多个请求复用。默认开启;
- pipeline(管线化):同一个TCP连接中,客户端可以同时发送多个请求,不必等待上一个请求返回结果后才发送下一个请求;
- Host:在1.0中默认每台服务器绑定唯一的IP地址,host字段指定IP地址上服务器的域名,用于处理一个IP地址上有多个虚拟主机的情况;
- 缓存机制:强缓存:Cache-control相对时间的优先级高于Expires绝对时间;协商缓存:Etag文件的特殊标识的优先级高于Last-Modified最后一次被修改的时间;
- Chunked机制:服务端返回数据时通常通过Content-length告知客户端数据大小,让客户端知道数据是否接受完毕。但当数据是动态产生的时,服务端也无法知道数据的具体大小,又不希望等数据完全加载完毕后再响应客户端,就可以采用chunked机制进行分块传输编码。服务器端需要在header中添加Transfer-Encoding: chunked来替代传统的Content-Length。编码使用若干个chunk组成,由一个标明长度为0的chunk结束。每个chunk有两部分组成,第一部分是该chunk的长度,第二部分就是指定长度的内容;
- 支持断点续传,通过使用请求头中的 Range 字段来实现。
- 新增五种请求方法:PUT、TRACE、OPTIONS、DELETE、CONNECT;
- 新增一系列状态码;
- 缺点:
- 仍存在队头阻塞(浏览器限制单个域名并行TCP连接数通常为6-8个);
- 无状态特性导致http头部重复携带;
- 明文传输不安全;
- 不支持服务端推送消息;
HTTP 2.0
- Header压缩:通过索引表将常用的HTTP Header存储,客户端与服务端各自缓存一份,在索引表中的Header只需要传输对应的索引,减少了Header的大小;
- 二进制分帧:HTTP/2.0引入了stream(流)和frame(帧)的概念,stream可以承载一个或多个frame,每个frame通过首部的Stream ID标识自己属于哪个stream;
- 多路复用:基于二进制分帧,解决HTTP队头阻塞。同一域名的所有请求和响应在单个连接上进行,每个request或response都是一个stream,每个stream可以由不同Stream ID的frame组成,接收方收到stream后,将相同的Stream ID的frame组装成完整的请求报文和响应报文;
- 服务器推送:浏览器发送一个请求,服务器主动向浏览器推送与这个请求相关的资源。比如请求HTML文件,服务端返回HTML文件和CSS文件。推送资源可以由不同页面共享,客户端可以缓存或拒收资源,客户端使用Cache Digest告诉服务器哪些已被缓存;
- 请求优先级:每个frame通过三个参数来定义资源的优先级,分别是:父级数据流(Parent Stream)、权重(Weight)、独占位(Exclusive Bit)。具体浏览器的实现不同;
- 缺点:
- TCP以及TCP+TLS建立连接的延迟(握手延迟);
- 解决了HTTP的队头阻塞,但TCP仍存在队头阻塞(连接双方的有任一个数据包丢失,或任一方的网络中断,整个TCP连接就会暂停,丢失的数据包需要被重新传输,从而阻塞该TCP连接中的所有请求,在网络较差或不稳定情况下,反而使用多个连接时的表现更好。);
HTTP 3.0
- 由于在限定条件下TCP很难解决队头阻塞问题,HTTP/3.0基于UDP实现;
- 有序交付:UDP是不可靠传输协议,在数据包中增加offset(偏移量)字段,接收端根据 offset 字段对异步到达的数据包进行排序,保证有序性;
- 队头阻塞:TCP队头阻塞是由于所有请求共享一个滑动窗口,HTTP/3.0给每个请求流单独分配滑动窗口,仅在单个数据流中存在队头阻塞;
- 连接迁移:当客户端切换网络时,服务端连接不会断开。而在TCP连接中基于4元组:源IP、源端口号、目的IP、目的端口号,任一发生改变都需要重新建立连接。HTTP/3.0基于64位的Connection ID建立连接,切换网络不用重新连接,根本原因是UDP是基于无连接的;
问题笔记
- 301重定向后POST请求被修改为GET请求
状态码 | 含义 |
---|
301 Moved Permanently | 永久移动,会变成 GET 请求(除非是安全请求) |
302 Found | 临时移动,默认也变为 GET 请求 |
307 Temporary Redirect | 临时重定向,保留原始方法(如 POST) |
308 Permanent Redirect | 永久重定向,保留原始方法 |