HTTP (HyperText Transfer Protocol) 超文本传输协议
HTTP/0.9 单行协议
- 请求由单行指令构成,以唯一可用方法
GET
开头,其后跟目标资源的路径(一旦连接到服务器,协议、服务器、端口号这些都不是必须的)。 - 只有
HTML
文件可以传送,无法传输其他类型的文件;也没有状态码或错误代码:一旦出现问题,一个特殊的包含问题描述信息的HTML
文件将被发回,供人们查看。
HTTP/1.0 构建可拓展性
- 协议版本信息现在会随着每个请求发送(
HTTP/1.0
被追加到了GET
行)。 - 状态码会在响应开始时发送,使浏览器能了解请求执行成功或失败,并相应调整行为(如更新或使用本地缓存)。
- 引入了
HTTP
头的概念,无论是对于请求还是响应,允许传输元数据,使协议变得非常灵活,更具扩展性。 - 在新
HTTP
头的帮助下,具备了传输除纯文本HTML
文件以外其他类型文档的能力(感谢Content-Type
头)。
HTTP/1.1 标准化的协议
- 连接可以复用,节省了多次打开TCP连接加载网页文档资源的时间。
- 增加管道技术,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
- 支持响应分块。
Transfer-Encoding: chunked
,将数据分为多块数据来传输。 - 引入额外的缓存控制机制。
- 引入内容协商机制,包括语言,编码,类型等,并允许客户端和服务器之间约定以最合适的内容进行交换。
- 感谢
Host
头,能够使不同域名配置在同一个IP地址的服务器上。
HTTP/2.0
HTTP/2
是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。- 这是一个多路复用协议。并行的请求能在同一个链接中处理,移除了
HTTP/1.x
中顺序和阻塞的约束。客户端发送多个请求和服务端给出多个响应的顺序不受限制。 - 压缩了
headers
。因为headers
在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。 - 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
- 对
Alt-Svc(Alternative-Service,备选服务)
的支持允许了给定资源的位置和资源鉴定,允许了更智能的CDN
缓冲机制,列举了当前站点备选的访问方式列表。 Client-Hints
的引入允许浏览器或者客户端来主动交流它的需求,或者是硬件约束的信息给服务端。通过新增的一系列头部字段带上分辨率、设备像素比、图片宽度等信息,使得各种复杂的策略可以挪到服务端去实现了。- 在
Cookie
头中引入安全相关的的前缀,现在帮助保证一个安全的cookie
没被更改过。 HTTP 1.1
取消数据流的唯一方法,就是关闭TCP
连接;HTTP/2
取消某一次请求,同时保证TCP
连接还打开着,可以被其他请求使用。客户端还可以指定数据流的优先级,优先级越高,服务器就会越早响应。
一些相关概念
referer
和Referrer-Policy
。referer
是浏览器为了告诉服务端用户的请求来源添加的字段。Referrer-Policy
定义浏览器添加referer
字段的策略。no-referrer
,整个Referer
首部会被移除。访问来源信息不随着请求一起发送no-referrer-when-downgrade
,在没有指定任何策略的情况下用户代理的默认行为。在同等安全级别的情况下,引用页面的地址会被发送(HTTPS->HTTPS),但是在降级的情况下不会被发送 (HTTPS->HTTP)。origin
,在任何情况下,仅发送文件的源作为引用地址。origin-when-cross-origin
,对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅发送文件的源。same-origin
,对于同源的请求会发送引用地址,但是对于非同源请求则不发送引用地址信息strict-origin
,在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。strict-origin-when-cross-origin
,对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。unsafe-url
,无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。
- 如何开启策略。
- 通过给
<a>
标签增加referrer
属性也可以指定Referrer-Policy
。<a href="http://example.com" referrer="no-referrer|origin|unsafe-url">xxx</a>
- 通过
meta
设置。<meta name="referrer" content="no-referrer">
- 通过给
keep-alive
,HTTP/1.1
之后是默认开启的。keep-alive
机制避免了频繁建立和销毁连接的开销。 同时,减少服务端TIME_WAIT
状态的TCP
连接的数量(因为由服务端进程主动关闭连接)keepalive_timout
:一个http
产生的tcp
连接在传送完最后一个响应后,还需要保持住keepalive_timeout
秒后,才开始关闭这个连接。keepalive_timout
设置不合理,反而会加重服务端的负担,长时间的TCP
连接容易导致系统资源被无效占用。- 与
TCP
的keepalive
区别在于HTTP
的keep-alive
是为了让TCP
连接保持得更久一点,而TCP
的keepalive
是一种检测TCP连接状态的保鲜机制,闲置了tcp_keepalive_time
后通过类似心跳检测的方式判断连接情况,并且会在没有收到对方的ack
包之后在tcp_keepalive_intvl
后会尝试tcp_keepalive_probes
次,最后还没有收到ack
包就断开此次连接。TCP
连接默认闲置时间是2小时,一般设置为30分钟足够了。
HTTPS
的数据加密传输过程。- 服务端使用非对称加密生成密钥对(公钥和私钥),把公钥发给客户端,客户端通过系统中内置的
CA
证书进行解密,解密成功客户端产生一个随机值(用来对数据进行对称加密的密钥client key),使用服务端的公钥对clinet key
进行加密后发给服务器,服务器使用私钥解密后拿到client key
。服务端使用client key
对数据进行对称加密,传输到客户端后,客户端使用client key
对数据进行对称解密,就拿到了服务端发送的数据了。 - 非对称加密的特点就是会有一组密钥对,公钥和私钥。使用公钥加密的数据可以被私钥解密,使用私钥加密的数据可以被公钥解密,反过来,能被公钥解密的数据一定是被私钥加密的,能被私钥解密的数据一定是公钥加密的。
- 对称加密就是使用共同的密钥,对一组数据进行加密和解密。
CA
证书解密失败后,就会告知用户,该网站的证书是不受信任的证书,这个警告在日常生活中很常见。CA
证书本质就是存放了证书申请机构的相关信息的被非对称加密的私钥加密过的密文,通过公钥能解密出CA
证书的内容就证明该公钥是来自受信任的机构或组织。- 一句话概括,使用非对称加密的密钥对传输对称加密的密钥,再使用该密钥对数据进行对称加密传输和对称解密以后使用。
- 服务端使用非对称加密生成密钥对(公钥和私钥),把公钥发给客户端,客户端通过系统中内置的
TCP
的三次握手和四次挥手。HTTP
本身是没有握手和挥手的,是指在建立和断开TCP
连接时的最小通信次数。- 三次握手。
- 客户端给服务端发申请连接报文,
SYN=1,seq=x
。明天一起吃饭? - 客户端回复可以连接的报文,
SYN=1,ACK=1,seq=y,ack=x+1
。可以啊。 - 客户端给服务端发确认连接的报文,
ACK=1,seq=x+1,ack=y+1
。好,不见不散。
- 客户端给服务端发申请连接报文,
- 四次挥手。
- 客户端数据传输完成后,向服务端发报文,
FIN=1,seq=u
。我吃完了,可以走了吗? - 服务端回复确认报文,
ACK=1,seq=v,ack=u+1
。知道了,等我吃完先。 - 服务端最后的数据发送完毕后发送断开的报文,
FIN=1,ACK=1,seq=w,ack=u+1
。我也吃完了,咱们走吧 - 客户端回复确认报文。
ACK=1,seq=u+1,ack=w+1
。好的,再见。
- 客户端数据传输完成后,向服务端发报文,
- 三次握手。
cookie
。用于储存web
页面的用户信息。- 存放位置是在客户端本地的,当用户发送请求到服务端时,会将
cookie
信息带到请求中发送给后端。 - 大小不超过4kb。
- 创建
cookie
的方式- 通过
response
中的Set-Cookie
响应头,直接设置,这种情况下一般是程序员在java
,c#
,php
等代码中直接操作cookie
会编译成这种情况。 - 通过
js
设置,document.cookie
。
- 通过
- 可选参数。
Name/Value
,设置Cookie
的名称及相对应的值,对于认证Cookie
,Value
值包括Web
服务器所提供的访问令牌。Expires
,设置Cookie
的生存期。有两种存储类型的Cookie
:会话性与持久性。Expires
属性缺省时,为会话性Cookie
,仅保存在客户端内存中,并在用户关闭浏览器时失效;持久性Cookie
会保存在用户的硬盘中,直至生存期到或用户直接在网页中单击“注销”等按钮结束会话时才会失效。Path
,定义了Web
站点上可以访问该Cookie
的目录。Domain
,指定了可以访问该Cookie
的Web
站点或域。Cookie
机制并未遵循严格的同源策略,允许一个子域可以设置或获取其父域的Cookie
。当需要实现单点登录方案时,Cookie
的上述特性非常有用,然而也增加了Cookie
受攻击的危险,比如攻击者可以借此发动会话定置攻击。因而,浏览器禁止在Domain
属性中设置.org
、.com
等通用顶级域名、以及在国家及地区顶级域下注册的二级域名,以减小攻击发生的范围。Secure
,指定是否使用HTTPS
安全协议发送Cookie
。HTTPOnly
,用于防止客户端脚本通过document.cookie
属性访问Cookie
,有助于保护Cookie
不被跨站脚本攻击窃取或篡改。但是,HTTPOnly
的应用仍存在局限性,一些浏览器可以阻止客户端脚本对Cookie
的读操作,但允许写操作;此外大多数浏览器仍允许通过XMLHTTP
对象读取HTTP
响应中的Set-Cookie
头。
cookie
的安全防护措施,增加MAC
地址进行完整性校验,使用密钥对cookie
进行加密处理,结合session
进行双重验证,在cookie
中添加后端随机生成的随机数。- 应用场景:
- 判断用户是否登录过网站。
- 记录用户的使用偏好做定制化服务。
- 存放位置是在客户端本地的,当用户发送请求到服务端时,会将
session
。用于储存特定用户会话所需的属性以及配置信息,保存用户当前的会话状态。- 存放位置是在服务端的文件、数据库或者内存中,它的运行依赖
session id
,而session id
是存放在cookie
中的,在用户第一次访问服务器时自动生成。 session
为了更好的节省资源,可以设置它的超时时间。- 应用场景:
- 记录当前会话。
- 实现单点登录。
- 存放位置是在服务端的文件、数据库或者内存中,它的运行依赖
token
。- 定义:
Token
是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token
便将此Token
返回给客户端,以后客户端只需带上这个Token
前来请求数据即可,无需再次带上用户名和密码。 - 背景:客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,
Token
便应运而生。 - 目的:为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
- 定义:
- 缓存相关的
header
属性。Expires
,响应过期的日期和时间,Expires: Thu, 01 Dec 2010 16:00:00 GMT
Cache-Control
,告诉所有的缓存机制是否可以缓存及哪种类型,Cache-Control: no-cache
no-cache
不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载no-store
直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源public
可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器private
只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存max-age
从当前请求开始,允许获取的响应被重用的最长时间(秒)
Last-Modified
,请求资源的最后修改时间,Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
ETag
,请求变量的实体标签的当前值,ETag: “737060cd8c284d8af7ad3082f209582d"