原文链接:https://github.com/helloyoucan/knowledge
HTTP相关
1、特点
- 简单快速(资源URL固定)
- 灵活(可传输不同类型的数据)
- 无连接(通讯结束则断开)
- 无状态(传输完成会断开,服务端无法区分)
2、报文组成
请求报文
- 请求头(http方法、当前地址、http协议、版本)
- 请求行(告知服务端需要的内容、内容类型)
- 空行(服务端把空行后的内容解析为请求体)
- 请求体
响应报文
- 状态行
- 响应头
- 空行
- 响应体
5、方法
- GET
- POST
- PUT
- DELETE
- HEAD(获取报头,与相比响应报文中少了响应体的内容)
GET | ||
---|---|---|
浏览器后退 | 无害 | 再次发送请求 |
URL地址 | 可被收藏 | 不可 |
参数 | 通过URL传递 | 存放在Request body中 |
参数限制 | 无(浏览器地址栏有限制) | 无 |
缓存 | 浏览器主动 | 需要手动设置 |
编码 | 只支持URL编码 | 支持多种 |
请求参数 | 浏览器保存在历史记录 | 不会保留 |
数据类型 | ASCII字符 | 没有限制 |
安全性 | 参数暴露在URL |
状态码
原因结语 | ||
---|---|---|
1XX | 信息性状态码 | 接收的请求正在处理 |
2XX | 成功 | 请求正常处理完毕 |
3XX | 重定向 | 需要进行附加操作以完成请求 |
4XX | 客户端错误 | 服务器无法处理请求 |
5XX | 服务器错误 | 服务器处理请求出错 |
常用的状态码
- 200 #请求成功
- 204 #请求成功处理,单响应报文中不含实体的主体部分(用于只需要从客户端发生信息,服务端不需要发送新的信息内容)
- 206 #客户端进行了范围请求,服务端成功执行了这部分get请求(例如视频分段加载,拖动视频进度条)
301 #永久性重定向(请求的资源已被分配了新的URL,以后应使用资源现在所指的URL)
302 #临时性重定向
303 #请求资源存在着另外一个URL,应使用GET方法定向获取请求的资源
304 #客户端发生附带条件的请求时,服务端允许请求访问资源,但未满足条件。
-
307 #临时性重定向。(重定向时,不会从POST请求变成GET)
301,302,303响应状态码返回时,几乎所有浏览器都会吧POST改成GET,删除请求报文主体,再次自动发送请求。但307不会
- 400 #请求报文存在错误
- 401 #发送的请求需要有同感HTTP认证(BASIC认证、DIGEST认证)的认证信息,若之前已进行1次请求,则表示认证失败
- 403 #请求的资源被服务器拒绝(未获得文件系统的访问权限,访问权限出现问题,从为授权的发送源IP地址视图访问等)
- 404 #无法找到资源(也可在服务器拒绝请求且不想说明理由时使用)
- 500 #服务端执行请求时发生错误
- 501#服务器不具备完成请求的功能
- 502 #网关错误,服务器无法重上游服务器收到无限响应
- 503 #服务端处于超负荷或在停机维护,无法处理请求
- 504 #网关超时
- 505 # http版本不支持
6、持久连接
- HTTP协议采用“请求-应答”模式,每次请求都要新建连接,完成后断开
- 使用K持久连接时,客户的到服务端的连接持续有效,后继请求时,不需重新建立连接
http1.0
- keep-alive补充协议,客户端与服务器之间完成了持久连接
- 使用HTTP/1.0的客户端在首部中加上”Connection:Keep-Alive”,请求服务端将一条连接保持在打开状态。服务端如果愿意将这条连接保持在打开状态,就会在响应中包含同样的首部。如果响应中没有包含”Connection:Keep-Alive”首部,则客户端会认为服务端不支持keep-alive,会在发送完响应报文之后关闭掉当前连接。
- http1.1废弃
http1.1
- 采取持久连接的方式替代了Keep-Alive
- 默认持久连接(Connection: keep-alive),需要关闭则在报文上加上Connection:Close首部,在HTTP/1.1中,所有的连接都进行了复用
- 如同Keep-Alive一样,空闲的持久连接也可以随时被客户端与服务端关闭。不发送Connection:Close不意味着服务器承诺连接永远保持打开
7、管线化(http1.1)
-
持久化连接的情况,某个连接上的消息类似
请求1 -> 响应1 -> 请求2 -> 响应2 -> 请求3 -> 响应3
-
管线化(通道持久建立,把全部请求打包一次性请求,把响应也全部打包一次性传输回去)
请求1 -> 请求2 -> 请求3 -> 响应1 -> 响应2 -> 响应3
- 管线化通过持久连接完成,仅http/1.1支持
- GET和HEAD可以,POST有所限制
- 不会应响应到来的顺序
- 要求服务器对管线化请求不失败
- 不能大幅度带来性能提升,服务端支持有限,浏览器默认不开启
- 现代浏览器Chrome和Firefox默认并未开启管线化支持
- 很多服务器端和代理程序对管线化的支持并不好
8、http协商缓存vs强缓存
强缓存(200)
浏览器在请求某一资源使,先获取该资源缓存的header信息,判断是否命中强缓存(expires和cache-control信息),命中则直接从缓存中获取资源信息,包括缓存header信息,该次请求不与服务器通讯。
expires #http1.0的规范,值为一个绝对时间的GMT格式的时间字符串(如Mon, 10 Jun 2015 21:31:12 GMT);在该时间前的请求,本地缓存始终有效,不会发送请求到服务器。
-
cache-control:max-age=number(秒) #http1.1出现大的header信息,利用max-age的值进行判断,是一个相对值。资源初次请求时间和Cache-Control设定有效期,计算资源过期时间,发送请求时将这个过期时间和请求时间对比。
cache-control 还有几个常用的值:
- no-cache # 不使用本地缓存。可使用协商缓存。
- no-store # 禁止浏览器缓存数据
- public #可被所有用户缓存,包括终端用户、CDN等中间代理服务器
- private # 只允许终端用户的浏览器缓存。
若同时存在,则优先级:cache-control > expires
协商缓存(304)
客户端与服务端通过某种标识进行通讯,让服务器判断请求资源是否可以缓存访问。不命中强缓存时,浏览器发送的请求到服务器,该请求携带第一次请求返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match)。服务器感觉相关的header信息对比协商缓存是否命中,命中则服务器返回新的header信息更新缓存中的对应header信息,但不返回资源内容,告知浏览器从缓存中获取,否则返回最新资源内容。
- 通过标识通讯
- 非初次请求携带缓存字段(Last-Modified/If-Modified-Since和Etag/If-None-Match)
- 返回304状态码,不返回资源
-
Last-Modified/If-Modified-Since # 值的格式是GMT格式的时间
- 初次请求,返回资源时,response的header上加上Last-Modified,表示资源在服务端的最后修改时间。
- 再次请求,request的header加上If-Modified-Since(初次请求时返回Last-Modified的值)。
- 服务端根据If-Modified-Since和资源在服务器上的最后修改时间对比,没变化则返回304 Not Modified,不返回资源内容。变化了则返回资源和Last-Modified。
-
Etag/If-None-Match # 服务器生成的唯一标识字符串
- 与Last-Modified/If-Modified-Since类似。
- 不一样的地方:返回304时,Etag重新生成,并在response header返回,即使该Etag与之前没有变化。
-
Last-Modified与Etag 对比
- 周期性修改的文件,内容不变而修改时间改变,使用Etag更好
- 频繁修改的文件(1s内修改几次),If-Modified-Since只能检查到秒级以上的,使用Etag更好
- 某些服务器不能精确文件的最后修改时间,使用Etag更好
- Etag更准确,可一起使用,Etag优先级高,先对比Etag,一致后再对比Last-Modified,再返回304
用户行为对缓存影响
用户操作 | Expires/Cache-Control | Last-Modified/Etag |
---|---|---|
地址栏打开 | yes | yes |
页面链接跳转 | yes | yes |
新开窗口 | yes | yes |
前进后退 | yes | yes |
F5刷新 | no | yes |
Ctrl+F5强制刷新 | no | no |
9、http2.0新特性
- 二进制格式 #HTTP1.x 的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认 0 和 1 的组合。
-
多路复用
- 同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗。
- 单个连接上可以并行交错的请求和响应,之间互不干扰
- keep-alive虽然可以用多次,但是同一时刻只能有一个HTTP请求
- header压缩 #HTTP2.0 使用 encoder 来减少需要传输的 header 大小,通讯双方各自 cache 一份 header fields 表,既避免了重复 header 的传输,又减小了需要传输的大小。
- 服务端推送 # 允许服务器在请求之前先推送响应信息到客户端
10、TCP三次握手
- 客户端 →服务端(你好,我是A) #客户端给服务器发送一个 SYN 报文
- 服务端 → 客户端 (收到,我是B) #服务器收到 SYN 报文之后,会应答一个 SYN+ACK 报文。
- 客户端 →服务端(那我们连接了) #客户端收到 SYN+ACK 报文之后,会回应一个 ACK 报文。
11、TCP四次挥手
- 客户端 →服务端(你好,我要关闭了)
- 服务端 → 客户端(稍等,还有最后一个包)
- 服务端 → 客户端(我已经好了,随时关闭)
- 客户端 →服务端(你关闭吧,不用回复,A等待2MSL无回复,关闭)
12、https(安全超文本传输协议)
是什么?
- 基于HTTP开发,用于客户计算机与服务器之间交互信息
- 使用安全套接字层(SSL)进行通讯交换
与HTTP区别
https协议需要到ca申请证书,一般免费证书很少,需要交费;
http 信息的明文传输,https则是具有安全性的ssl加密传输协议;
端口不一样,http是80,https是443;
HTTPS协议是由SSL + HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。