HTTP(Hypertext Transfer Protocol)是以 TCP/IP(Transmission Control Protocol/Internet Protocol)协议族为基础的,属于 TCP/IP 内部的一个子集;TCP/IP 协议族按层次分别分:
利用 TCP/IP 进行网络通信时,会通过分层顺序与对方进行通信;发送端从应用层往下走,接收端则从链路层往上走;发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息;反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
IP 网际协议位于网络层,用于把各种数据包传送给对方;要保证数据传送到对方那里,需要满足两个重要的条件:IP 地址和 MAC(Media Access Control Address)地址。
IP 间的通信依赖 MAC 地址,通信双方通常是经过多台计算机和网络设备中转才能连接到对方;而在进行中转时,会利用下一站中转设备的 MAC 地址来搜索下一个中转目标;这时,会采用 ARP(Address Resolution Protocol)协议,根据通信方的 IP 地址就反查出对应的 MAC 地址。
TCP 位于传输层,在发送数据前,通信双方必须在彼此间建立一条连接;为了方便传输,TCP 字节流服务会将大块数据分割成以报文段为单位的数据包进行管理;为了准确无误地将数据送达目标处,TCP 协议采用了三次握手四次挥手策略。
客户端和服务端通信前要进行连接,“三次握手”的作用就是双方都能明确自己和对方的收发能力是正常的。
第一次握手:客户端发送网络包,服务端收到了;这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了;这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。
第三次握手:客户端发包,服务端收到了;这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。
TCP 断开链接的过程和建立链接的过程比较类似,只不过中间的两部并不总是会合成一步走,所以它分成了 4 个动作;之所以中间的两个动作没有合并,是因为 TCP 存在「半关闭」状态,也就是单向关闭。
上面有一个非常特殊的状态 time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是 4 分钟,4 分钟后才会进入到 closed 状态,释放套接字资源。
DNS(Domain Name System)服务是和 HTTP 协议一样位于应用层的协议;它提供域名到 IP 地址之间的解析服务。
URI(统一资源标志符)就像是人的身份证号,可以把人独一无二地表示出来;URL(统一资源定位符)就像是人的居住地址,我们也可以通过住址找到这个人;不论是用定位的方式还是用编号的方式,我们都可以唯一确定一个人,都是 URI 的一种实现,而 URL 就是用定位的方式实现的 URI。
HTTP 协议和 TCP/IP 协议族内的其他众多的协议相同,用于客户端和服务器之间的通信;请求访问文本或图像等资源的一端称为客户端,而提供资源响应的一端称为服务器端。
HTTP 是一种无状态协议,自身不对请求和响应之间的通信状态进行保存;也就是说 HTTP 对于发送过的请求或响应都不做持久化处理。cookie 技术通过在请求和响应报文中写入 cookie 信息来控制客户端的状态;cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 cookie;当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 cookie 值后发送出去;服务器端发现客户端发送过来的 cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
用于 HTTP 协议交互的信息被称为 HTTP 报文;请求端的 HTTP 报文叫做请求报文,响应端的叫做响应报文;HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本;HTTP 报文大致可分为报文首部和报文主体两块。
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。
HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点,可以用一台服务器为多位客户服务,也可以以每位客户持有的域名运行各自不同的网站。
在互联网上,域名通过 DNS 服务映射到 IP 地址;当请求发送到服务器时,已经是以 IP 地址形式访问了;在相同的 IP 地址下,由于虚拟主机可以寄存多个不同主机名和域名的 Web 网站,因此在发送 HTTP 请求时,必须在 Host 首部内完整指定主机名或域名的 URI。
HTTP 通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理、网关和隧道…
代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器;代理不改变请求 URI,会直接发送给前方持有资源的目标服务器。
在 HTTP 通信过程中,可级联多台代理服务器;请求和响应的转发会经过数台类似锁链一样连接起来的代理服务器。转发时,需要附加 Via 首部字段以标记出经过的主机信息。
使用代理服务器的理由有:利用缓存技术减少网络带宽的流量(缓存代理)、组织内部针对特定网站的访问控制、获取访问日志、透明代理…
网关的工作机制和代理十分相似;而网关能使通信线路上的服务器提供非 HTTP 协议服务;利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。
隧道可按要求建立起一条与其他服务器的通信线路,使用 SSL 等加密手段进行通信;隧道的目的是确保客户端能与服务器进行安全的通信;隧道本身不会去解析 HTTP 请求。隧道会在通信双方断开连接时结束。
在请求中,HTTP 报文由方法、URI、HTTP 版本、HTTP 首部字段等部分构成。
在响应中,HTTP 报文由 HTTP 版本、状态码(数字和原因短语)、HTTP 首部字段 3 部分构成。
通用首部字段:
请求首部字段:
响应首部字段:
实体首部字段:
Cookie 相关首部字段:
其他首部字段:
HTTP 缓存分为 2 种,一种是强缓存,另一种是协商缓存;主要作用是可以加快资源获取速度,提升用户体验,减少网络传输,降低运营成本,缓解服务端的压力。
强缓存不需要发送请求到服务端,客户端直接读取本地缓存;由 Expires、Cache-Control 和 Pragma 3 个 Header 属性共同来控制。
当强缓存失效或者被禁用的时候,客户端会到服务端去协商;如果命中了协商缓存,服务器会返回 304,告诉客户端使用协商缓存。
HTTP 的缺点:
即使已经过加密处理的通信,也会被窥视到通信内容,这点和未加密的通信是相同的;只是说如果通信经过加密,就有可能让人无法破解报文信息的含义,但加密处理后的报文信息本身还是会被看到的。
加密技术:通信加密、内容加密。
HTTP 协议中的请求和响应不会对通信方进行确认,因此会存在以下各种隐患:
HTTP 协议无法证明通信的报文完整性;没有任何办法确认,发出的请求/响应和接收到的请求/响应是前后相同的;请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击(Man-In-The-Middle Attack)。
HTTPS 并非是应用层的一种新协议,只是 HTTP 通信接口部分用 SSL 和 TLS 协议代替;通常,HTTP 直接和 TCP 通信,当使用 SSL 时,则演变成先和 SSL 通信,再由 SSL 和 TCP 通信了;不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL 协议使用。
对称密钥加密:加密和解密同用一个密钥;非对称密钥加密:私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
HTTPS 采用“对称密钥加密”和“非对称密钥加密”两者并用的混合加密机制,“非对称密钥加密”用于交换“对称密钥加密”的密钥,“对称密钥加密”用于通信。
如何证明公开密钥本身就是货真价实的公开密钥呢?可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书。
首先,服务器的运营人员向数字证书认证机构提出公开密钥的申请;数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。
服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信;公钥证书也可叫做数字证书或直接称为证书。
接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥的是真实有效的数字证书认证机构;二,服务器的公开密钥是值得信赖的。
此处认证机关的公开密钥必须安全地转交给客户端;多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。
HTTP Strict Transport Security 是一个安全功能,它告诉浏览器只能通过 HTTPS 访问当前资源。
当请求由 HTTP 跳转到 HTTPS 时,HSTS 可以阻止用户被中间人攻击。
|
|
max-age=<expire-time> 表示在浏览器收到这个请求后的 <expire-time> 秒的时间内,凡是访问这个域名下的资源都使用 HTTPS 请求。 includeSubDomains 表示此规则也适用于该网站的所有子域名。 preload 表示浏览器将会永不使用非安全的方式连接到你的域名。
原理是攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载;用户在登录状态下这个请求被服务端接收后会被误以为是用户合法的操作。
最简单的 CSRF 攻击:
进阶 CSRF 攻击:
危险网站可以伪造一个表单并隐藏,并在自己网站的 onload 事件中,触发这个表单的提交事件,就可以改 GET 攻击为 POST 攻击。
CSRF 防范思路:
CSRF 防范手段:
向页面里插入恶意 Script 代码(代码注入型攻击);当用户浏览该页时,嵌入其中 Script 代码会被执行,从而达到恶意攻击用户的目的;归根结底,XSS 就是想办法让用户的浏览器去执行一些这个网页中原本不存在的前端代码。
XSS 的危害:
如何利用 XSS:
XSS 防范手段:
CORS 请求的选择同意认证机制由底层处理,请求发出后,浏览器自动追加受保护的 Origin 首部,包含着发出请求的来源;相应地,远程服务器可以检查 Origin 首部,决定是否接受该请求,如果接受就返回 Access-Control-Allow-Origin 响应首部:
|
|
thirdparty.com 决定同意与 example.com 跨源共享资源,因此就在响应中返回了适当的访问控制首部;假如它选择不同意接受这个请求,那么只要不在响应中包含 Access-Control-Allow-Origin 首部即可;这样,客户端的浏览器就会自动将发出的请求作废;如果第三方服务器不支持 CORS,那么客户端请求同样会作废。
CORS 还允许服务器返回一个通配值(Access-Control-Allow-Origin: *),表示它允许来自任何源的请求。
对于 CORS,浏览器还会采取一系列安全措施:
要启用 cookie 和 HTTP 认证,客户端必须在发送请求时发送额外的属性(withCredentials),而服务器也必须以适当的首部(Access-Control-Allow-Credentials)响应,表示它允许应用发送用户的隐私数据;如果客户端需要写或者读自定义的 HTTP 首部,或者想要使用“不简单的方法”发送请求,那么它必须首先要获得第三方服务器的许可,即向第三方服务器发送一个预备(preflight)请求:
|
|
HTTP/2 的出现,相比于 HTTP/1.x,大幅度的提升了性能;在与 HTTP/1.1 完全语义兼容的基础上,进一步减少了网络延迟。
多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息;众所周知,在 HTTP/1.1 协议中「浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制;超过限制数目的请求会被阻塞」;这也是为何一些站点会有多个静态资源 CDN 域名的原因之一。而 HTTP/2 的多路复用则允许同时通过单一的 HTTP/2 连接发起多重的请求 - 响应消息。
因此 HTTP/2 可以很容易的去实现多流并行而不用依赖建立多个 TCP 连接,HTTP/2 把 HTTP 协议通信的基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息并行地在同一个 TCP 连接上双向交换消息。
在不改动 HTTP/1.x 的语义、方法、状态码、URI 以及首部字段的情况下,HTTP/2 是如何做到「突破 HTTP/1.x 的性能限制,改进传输性能,实现低延迟和高吞吐量」的?关键之一就是在应用层(HTTP)和传输层(TCP or UDP)之间增加一个二进制分帧层。
HTTP/1.x 以换行符作为纯文本的分隔符,而 HTTP/2 将所有传输的信息分割为更小的消息和帧,并采用二进制格式对它们编码。
在二进制分帧层中,HTTP/2 会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码,其中 HTTP/1.x 的首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到 DATA frame 里面;HTTP/2 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。
在过去,HTTP 性能优化的关键并不在于高带宽,而是低延迟;TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度;这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。
HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升;单连接多资源的方式,减少服务端的链接压力,内存占用更少,连接吞吐量更大;由于 TCP 连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少;使拥塞和丢包恢复速度更快。
HTTP/1.x 并不支持 HTTP 首部压缩,为此 SPDY 和 HTTP/2 应运而生,SPDY 使用的是通用的 DEFLATE 算法,而 HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法。
服务端推送是一种在客户端请求之前发送数据的机制。在 HTTP/2 中,服务器可以对客户端的一个请求发送多个响应;Server Push 让 HTTP/1.x 时代使用内嵌资源的优化手段变得没有意义。
如果一个请求是由你的主页发起的,服务器很可能会响应主页内容、Logo 以及样式表,因为它知道客户端会用到这些东西;这相当于在一个 HTML 文档内集合了所有的资源,不过与之相比,服务器推送还有一个很大的优势:可以缓存!也让在遵循同源的情况下,不同页面之间可以共享缓存资源成为可能。
缓存位置:
用户行为:
HTTP 是一种无状态协议,每个请求都是独立存在的,服务端无法区分当前在给谁提供服务,所以才有了 cookie、session 和 token;它们是一种客户端身份凭证,用来告诉服务端‘我’是谁。