常用HTTP请求方法及区别对比 (Get、Post区别)
GET: 应该只用于获取数据
HEAD:获取数据,但接收的返回数据没有请求体部分
POST:用于提交指定资源,通常会导致服务器的状态变化或副作用
PUT:请求有效载荷替换目标资源(阿里云OSS)
DELETE: 删除指定资源
PATCH:对资源应用部分修改
OPTIONS:描述目标资源的通信选项
CONNECT:建立到目标资源服务器的隧道
TRACE:沿着到目标资源的路径执行消息环回测试
GET VS POST:
- get数据在URL可见,post通过表单提交在URL不可见,因此post更安全
- URL最多2048个ASCII字符,get数据在URL有长度限制, post无限制;
- 后退、刷新页面,Post会重新提交表单
- get可被收藏为书签、参数保留在历史、能被缓存;post不可收藏参数不会保存在历史,不可被缓存
常用HTTP状态码
100: Continue (继续)
200: OK (请求成功)
201: Created (成功创建新资源)
202: Accepted (请求收到但无响应)
301: Moved Permanently (永久移动到新的URI)
302: Found (临时移动,URI不变)
304: Not Modified (资源未修改)
400: Bad Request (错误请求,有语法错误)
401: Unauthorised (未授权,要求身份验证)
403: Forbidden (服务端拒绝请求)
404: Not found(资源未找到)
405: Method not allowed (请求的方法被禁用)
500: Internal Server Error(内部错误)
501: Not Implemented (尚未实施,不具备功能)
502: Bad Gateway (网关得到错误响应)
HTTP请求头结构
- Accept:可接受的响应数据类型 Accept:text/html
- Accept-encoding:浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法 (gzip)
- Accept-language:接收语言如zh-CN
- Connection:是否为长连接keep-alive / close
- Host:URL中提取的主机和端口号
- Referer:告诉服务器请求来源
- User-Agent:客户端使用的操作系统和浏览器的名称和版本
- Cache-Control:
private(default): 响应不能在用户间共享,只能作为私有缓存
public: 响应被缓存,并在用户间共享
must-revalidate: 缓存的响应被认为陈旧时,会到服务端确认是否最新。
no-cache: 响应仍会被缓存,但每次在使用已拥有的缓存之前都需要向服务器重新验证。
no-store:响应完全不会被缓存到客户端磁盘里(基于安全考虑的敏感响应会使用)
max-age=10:设置缓存最大有效时间,单位秒 - Cookie:当前已设置的cookie信息
- If-Modified-Since:向服务器协商缓存,查找对应时间之后资源是否更新,更新则返回200,未变更则返回304
- If-None-Match:为Etag值,让服务器对比对应资源的Etag是否相同,不同则说明资源更新。详见:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match
HTTP响应头结构
Connection: 同请求头
Content-Encoding:内容压缩方法 (端到端,会被缓存)
Transfer-Encoding:同上(逐跳,不会被缓存)
Content-Type: 响应内容的数据格式
Etag:返回资源版本的唯一标识
Keep-Alive:设置当前连接的超时时长和最大请求次数
Last-Modified:服务器认为的资源最后更新时间(Etag失效时的兜底机制)
Server:提供服务的软件
-
Set-Cookie:
<cookie-name>=<cookie-value> 设置cookie键值对
Max-age=<number> 离过期的剩余时间(比Expires优先级更高)
Expires=<date> cookie的最长有效时间
Domain=<domain-value> cookie可送达的主机名
Path=<path-value> 指定一个 URL 路径,这个路径必须出现在要请求的资源的路径中
Secure:使用https时,防止中间人攻击
HttpOnly:用于阻止 JavaScript 通过 Document.cookie 属性访问 cookie
SameSite=<samesite-value>:- Strict: 对第三方站点绝对不发送cookie;
- Lax(default):对第三方站点的子请求(如加载图片)不带cookie, 直接导航到第三方站点会发送;
- None: 对所有跨站请求都发送cookie, 【SameSite=None; Secure】必须同时设置Secure.
Access-Control-Allow-Origin:* / <origin> 允许共享响应资源的站点来源
Access-Control-Allow-Methods:针对预检请求,返回服务端允许响应的请求方法(列表)
Access-Control-Allow-Credentials: true 请求要求包含 credentials。需要与
XMLHttpRequest.withCredentials
或 Fetch API 的Request()
构造函数中的credentials
选项结合使用,才能完成带credential的CORS跨域请求。
HTTP VS HTTPS
HTTP是万维网服务器传输超文本时需要遵守的超文本传输协议
HTTPS是在HTTP基础上加上SSL加密层,防止中间人攻击,提升传输数据的真实性和可靠性
HTTPS优点:有加密,安全性高
HTTPS缺点:
1)HTTP连接简单,无状态。HTTPS握手比较费时,页面加载时间延长50%,增加10%-20%的耗电量。
2)HTTPS缓存不如HTTP高效,会增加数据开销。
3)HTTPS需要CA证书,费用较高。
4)SSL证书需要绑定IP,一个IP又只有一个域名,IPV4资源支持不了这种消耗
HTTP1.0 VS HTTP1.1 VS HTTP2.0 VS HTTP3.0
HTTP1.0
无连接无状态的,Connection: close;
每次请求都要建立一个TCP连接,服务器每次处理完就断开连接,也不跟踪客户端和不记录历史请求。
HTTP1.1
默认使用Connection: keep-alive;长连接。
通过 Content-Length 字段来判断当前请求的数据是否已经全部接受。
不允许同时存在两个并行的响应。
优点:
HTTP1.1通过建立持久连接,降低了重复断开重连的额外开销,支持多请求并行发送。
缺点:
- 高延迟,带来页面加载速度的降低。(网络延迟问题主要由于队头阻塞Head-of-line Blocking,导致宽带无法被充分利用)
Chrome限制一个域名下最多同时存在6个TCP连接,一个连接管道一次只能通过一个请求,超过的部分就要排队等待。
优化方案:- 同一页面资源分散到不同域名,以提升连接数上限。
- 合并小文件减少请求数(图片、js文件)。
- 内联图片原始数据减少请求数。
- 无状态特性,带来巨大的Http头部。
- 明文传输,不安全。
- 不支持服务器推送消息。
面试问题:HTTP1时代,把资源部署在不同域名下,为什么
一个TCP连接同一时间只支持一个请求,而浏览器对一个域名下的TCP连接数有限制,为了同时处理更多的请求,将资源部署在不同域名下以提升连接数上限。
HTTP2.0
基于SPDY协议,专注于性能,目标是让用户和网站间只使用一个连接。
新特性:
1、支持二进制传输:数据可细分为更小的帧,使用二进制编码发送;可乱序,接收方根据帧的流标识重新组装数据。
2、Header压缩:使用HPACK算法,建立头部键值对表,每次请求只发送与之前有差异的数据
3、多路复用:单个连接可以承载任意数量的双向数据流,数据分帧可重组。一个域名一个连接,并行的请求响应互不影响,请求包含优先值,可计算最优处理策略。
4、服务端推送:服务端可以主动发送CSS、JS资源,不需要客户端解析HTML时再请求。客户端可选择是否接收,主动推送也遵守同源策略。
5、提高安全性,很多浏览器只支持加密的HTTP2, 事实上都加了TLS/SSL加密层使用https
缺点:
1、TCP 以及 TCP+TLS 建立连接的延时:TCP三次握手+TLS1.2/TLS1.3的安全连接握手
2、TCP 的队头阻塞并没有彻底解决:出现丢包要求重传时,一个TCP通道内的所有请求都会被阻塞,HTTP2甚是不如HTTP1, 因为HTTP1还有多个TCP管道可处理其他请求。
3、多路复用导致服务器压力上升:没有限制请求上限,服务端可能出现瞬时QPS(queries/s)暴增
4、多路复用容易 Timeout: 网络带宽和服务器资源被大批量的请求稀释,造成timeout
HTTP3
基于UDP不需要握手,效率高 (0RTT)
RTT (Round-Trip Time) 发送端发送数据到接收到ACK数据的时间
TCP三次握手 - 1.5 RTT;TLS握手 - 1~2 RTT
新功能:
1.QUIC(Quick UDP Internet Connection)实现了可靠传输
- 可插拔:应用程序层面就能实现不同的拥塞控制算法。
- 单调递增的 Packet Number:代替TCP 的 seq。
- 不允许违约:一个 Packet 只要被 Ack,就认为它一定被正确 接收。
- 前向纠错(FEC - Forward Error Correction)
- 更多的 Ack 块和增加 Ack Delay 时间。(改善了拥塞控制机制)
- 基于 stream 和 connection 级别的流量控制。
【QUIC主要优点:0-RTT 的连接建立时间;丢失恢复机制改善,引起更少的timeout重发问题;头部信息少】
- 实现快速握手,基于UDP无需握手,QUIC也只需0-1RTT的握手时间
- 默认使用TLS1.3进行加密
- 彻底解决队头阻塞的多路复用:QUIC实现了在同一物理连接上可以有多个独立的逻辑数据流,独立传输,不会因其他请求而被阻塞。
- 连接迁移:QUIC由Connection ID(64bit)区分连接,只要Connection ID不变,连接就不需要重新建立,即便客户端网络IP发生变化。同一连接使用相同密钥,QUIC提供迁移客户端的自动加密验证。
- 传输可扩展
- 可选的不可靠传输
拥塞控制 & 流量控制
流量控制是避免发送方填满接收方的空闲空间
拥塞控制是避免发送方填满整个网络。
没有拥塞控制,发送方不停发送将造成延时、丢包,导致TCP要求重传,更加阻塞网络。
发送方如何判定网络出现阻塞?
发送方在规定时间内没有收到ACK报文(也就触发了超时重传)。
拥塞窗口:发送方维护的一个状态变量,它会根据网路拥堵情况动态调节。
之前发送窗口约等于接收窗口,但在拥塞窗口加入后,发送窗口=min(拥塞窗口, 接收窗口)。
拥塞窗口的变化规则
只要网络中没有出现阻塞,窗口就会增大
网络中出现阻塞,窗口就会减小
TCP VS UDP
TCP: Transmission Control Protocol
UDP: User Datagram Protocol
- TCP是面向链接的,而UDP是面向无连接的。
- TCP仅支持单播传输,UDP 提供了单播,多播,广播的功能。
- TCP的三次握手保证了连接的可靠性,具体方法包括对字节流分段并进行编号(保证数据包顺序正确),ACK回复和超时重发机制(保证顺利接收);
UDP是无连接的、不可靠的一种数据传输协议,首先不可靠性体现在无连接上,通信都不需要建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收。 - UDP的头部开销比TCP的更小,数据传输速率更高,实时性更好。
TCP三次握手和四次挥手
三次握手:
第一次握手,建立连接时客户端向服务器发送SYN码(SYN=x)进入SYN_SENT状态,等待服务器返回确认。
第二次握手,服务端接收到SYN包返回确认信息ack=x+1,同时发送自己的SYN=y给客户端 (即SYN+ACK包),进入SYN_RECV。
第三次握手,客户端收到服务端返回的SYN+ACK包,发送确认码ack=y+1, TCP连接进入ESTABLISHED状态。
从第三次握手开始,可以携带payload数据。四次挥手:客户端/服务端均可主动发起挥手。
第一次挥手:客户端发送FIN和序列号seq=u, 停止发送数据,主动关闭TCP连接。进入FIN_WAIT1状态。
第二次挥手:服务端接收到FIN报文,返回ack=u+1, 表明已接收,进入CLOSE_WAIT状态。此时TCP处于半关闭状态,客户端到服务端的连接已释放,进入FIN_WAIT2状态。
第三次挥手:如果服务端没有需要发送的数据了,也想关闭连接,则向客户端发送FIN,序列号seq=w 和之前的确认码ack=u+1, 进入LAST_ACK状态。
第四次挥手:客户端收到服务端的FIN后,返回确认码ack=w+1, 序号seq=u+1,进入TIME_WAIT状态。此时服务端依旧没有完全关闭连接,需等待一段时间确认服务端就收到客户端的ACK,才真正CLOSED。