HTTP学习总结【Ultra版】

326 阅读38分钟

五老峰HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准,可以说Web是建立在HTTP协议上通信的。

准确的说HTTP应该翻译为超文本转移协议。

在学习过程中,大瑞遇到几个疑问:

  • 超文本一词是如何诞生的?

  • HTTP出现以前,计算机之间是如何通信的?

  • HTTP诞生后的发展过程?

    有问题那就学嘛,于是就有了下面的内容。

​ 早在上世纪三十年代,美国 MIT 工程学院的电子工程师 Vannevar Bush(我也不知道怎么读🙈~)就提出了一种信息扩展存储器的设想:

可以将聚合起来的知识存储在微缩胶卷上,可以极其方便快速地查阅。并且这些信息应当有上下文关联性,就像人类大脑构建的知识链接那样。

​ 尽管他设想的扩展存储器系统从未实现,其思想却影响了后来者。

​ 1965 年,超文本一词首次出现在 Ted Nelson 发表的文章中,Nelson 是一位软件设计师。这位大佬提出的超文本一词含义如下:

大量的书面材料或图像材料以复杂的方式相互联系,因此不便在纸介质上呈现或展示。其中可能包含内容摘要,或者内容分布的脉络图以及各部分的内在联系;也可能包含审阅过其中内容的学者所添加的注释、补充或脚注。

​ Nelson 想要建立“文档库”,让信息之间互相关联,永不删除,并且方便所有人获取。20 世纪 70 年代,基于 Bush 的思想,Nelson 在他的 Xanadu 项目中实现了一个超文本系统的原型。

​ 很遗憾,该项目没有完成,但为后来者提供了基础,没白忙活。

​ 1975年1月,世界上第一台个人计算机 Altiar 8800 诞生。随后的十年间,个人计算机迎来高速发展。在这期间计算机面临一个问题:如何解决个人计算机之间的信息共享?

  • 独立模式

​ 在计算机发展的早期阶段,计算机都是以单机模式(独立模式)运行的。各个终端之间信息不能共享。

​ 计算机之间完全是割裂的,就像你手机开不了流量连不了无线,也没有蓝牙,可以想象下有多痛苦。

独立模式

  • 网络互联模式

    为解决单机某事的痛点,网络互联模式诞生。

​ 网络互联模式将一个个计算机连接在一起,形成一个计算机网络。连接多台计算机可以实现信息共享,同时还能在两台物理位置较远的机器之间即时传递信息。

网络互联模式 ​ 网络互联模式又分为两种模式,根据其规模可分为WAN(Wide Area Network,广域网)和LAN(Local Area Network,局域网)

  • 广域网指覆盖多个远距离区域的远程网络。

  • 比广域网再小一级的、连接整个城市的网络叫城域网(MAN, Metropolitan Area Network)。

  • 局域网指一个楼层、一栋楼或一个校园等相对较小的区域内的网络。

局域网

广域网 ​ 这两个技术使多台物理空间较远的机器之间的信息共享的需求得以实现。形成早期的计算机网络。

​ 但广域网与局域网本质上还是各个独立团体或者公司之间的私有网络,这时人们想要将各个私有网络连接为更大的私有网络。广域网与局域网也为自身技术限制暂时不能满足这种需求。

  • 诞生

​ 时间来到了1989年3月,CERN(欧洲核子研究组织)的蒂姆·伯纳斯-李提出了一种能让远隔两地的研究者们共享信息的设想。基本理念是通过借助多文档之间相互关联形成的超文本,连成可相互参阅的WWW(万维网)。

膜拜大佬

WWW(万维网)构成:

  • 把SGML作为页面的文本标记语言的HTML
  • 作为文档传递协议的HTTP
  • 指定文档所在地址的URL

​ 1990年1月,CERN研发出世界上第一台Web服务器和Web浏览器。

​ 1991年,HTTP/0.9发布。至此HTTP 诞生。

HTTP/0.9

​ HTTP/0.9的诞生具有划时代的意义,它打破了计算机信息数据共享的物理空间限制。

但是它并不完美:

  • 仅支持GET方法
  • 没有HEADER等数据描述信息
  • 服务端发送完毕即断开TCP连接
  • 可发送的数据仅限于HTML格式的字符串
  • 设计目标就是获取HTML
// HTTP/0.9
GET /index.html

<html>
  <body>Hello DaRui</body>
</html>

​ 在1991年-1996年期间,HTTP的发展一直处于驻足不前的状态。伴随HTTP的诞生,创办网景公司的马克·安德森于1994年发布了第一款浏览器Netscape0.9。让数百万用户第一次涌入了互联网世界的大门。开启了Web时代。

​ 当时以操作系统一统天下的微软意识到了网景浏览器对于操作系统的威胁。于1996买下Mosaic,开发了IE,浏览器大战,一触即发。后来就是微软利用其自身操作系统市场份额的优势,坐上了浏览器市场的头把交椅。

​ 浏览器大战,导致两家公司无视Web发展标准,各自对HTML进行扩展。最终导致前端工程师在开发时不得不考虑浏览器的兼容问题。

HTTP/1.0

​ 时间来到了1996年5月,由于HTTP0.9自身的局限性太多,所以针对其限制,HTTP/1.0 横空出世。协议雏形形成。

  • 可发送内容格式:图像、视频、二进制文件、文字。
  • 新增支持方法POSTPUTHEADDELETELINKUNLINK
  • 优化请求格式:头信息 + 元数据
    • 头信息可用于描述元数据
  • 新增状态码1XX2XX3XX4XX5XX
    • 明确客户端与服务端处理请求的状态
  • 新增其他内容:多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

主要缺点:

  • 每个TCP连接只能发送一个请求。发送数据完毕,连接就会关闭,如果还要请求其他资源,就必须重新建立连接。
  • 由于TCP的连接与断开过程成本大,尤其是当一个网页加载过多外部资源的时候,会给客户端与服务端之间的通信造成巨大压力。

HTTP/1.1

​ 1997年1月,HTTP/1.1 发布,只比 HTTP/1.0 版本晚了半年。可将它视为对1.0的补丁。

​ HTTP/1.1 一直用到了20年后的今天,直到现在还是最流行的版本。相较于HTTP/1.0,HTTP/1.1做了以下改进:

  • 引入持久连接 。Connection: keep-alive, 解决1.0中频繁需要进行TCP连接的问题,减少了建立和关闭连接的消耗和延迟。
  • 管线化传输(pipelining)。允许同时发送多个请求,不需要一个接一个的等待请求响应。允许在同一TCP连接中发送多个请求。
  • Content-Length 字段。一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是Content-length字段的作用,声明本次回应的数据长度。
  • 分块传输编码。允许HTTP由服务器发送给客户端的数据可以分成多个部分。使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小
  • 增强缓存处理,进一步完善协商缓存与强制缓存。在 HTTP1.0 中主要使用 header 里的If-Modified-SinceExpires来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略例如Entity tagIf-Unmodified-Since, If-Match``, If-None-Match等更多可供选择的缓存头来控制缓存策略。
  • 完善HEADER信息,新增状态码,新增请求方法:OPTIONSTRACECONNECT持久连接

主要问题:

  • 队头阻塞。复用TCP连接虽减少了重复连接的损耗,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。
  • 头信息臃肿。因为1.1给HEAD新增了一些描述请求的信息。在一定程度上增加了传输的成本。
  • 持久连接给服务端造成的性能压力
  • 数据安全。1.1 在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性。

​ HTTP/1.1的出现使HTTP协议功能已基本完备,在后续的很多年中,该版本非常吃香。后续推出的版本基本都是针对协议特点和缺点进行的调整、补充、和优化。先补充一波HTTP协议发展至1.1的特点和协议,之后我们继续唠。

HTTP协议的特点和所面临的问题

特点

  • 无状态协议。HTTP是无状态协议,它不对之前发生过的请求和响应的通信状态进行管理、保存,也就是说,无法根据之前的状态进行本次的请求处理。
    • 优点:由于不必保存状态,自然可以减少服务器的CPU及内存资源的消耗。
  • 灵活可扩展。HTTP允许传输任意类型的数据对象。传输时只需使用Content-Type加以标记即可。
  • 一请一答。HTTP支持客户端/服务端模式,是一种请求/响应模式的协议。
    • 如果服务端想主动推送消息怎么办?抱歉不行,这就有了HTTP/2.0的服务端推送。
  • 简单快速。客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GETHEADPOST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

​ 关于无连接,由于无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。起初采用这种方式目的是节省传输时间。但是每次建立连接需要重启TCP/IP的三握四挥,影响性能效率。

​ 故HTTP/1.1出现了持久连接,ConnectioonKeep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了建立或者重新建立连接,做到了在一个TCP链接中可以进行多次请求。但问题就是长时间的Keep-Alive也会影响服务器性能。

缺点

  • 通信使用明文传输(不加密),内容可能会被窃听
    • TCP/IP是可被窃听的网络。数据在传输过程中,各个网络节点不可控,有可能被抓包或者嗅探工具获取。
    • 加密处理防止被窃听。通信加密(SSL/TLS)+ 内容加密。
  • 不验证通信方的身份就可能遭遇伪装
    • 无状态的特点导致任何人都可以发起请求。无法认证目标。
    • 解决办法,开具查明对手的证书——第三方机构
  • 无法证明报文完整性,可能已遭篡改
    • 接收到的内容可能有误,既无法确认客户端下载的文件和服务器上的文件是否前后一致。
    • 防止篡改:采用Connect-MD5SHA-1散列值校验方法,以及用来确认文件的数字签名方法。

HTTPS

​ 上面总结了一波HTTP的特点和问题,缺点简单说就是安全性不行:不加密 + 无认证 + 无法确认完整性。于是HTTPS = HTTP + 加密 + 认证 + 完整性保护 。 HTTPS

  • HTTPS是新的协议吗?
    • 不是,HTTPS就是HTTP + SSL/TLS。
    • 通常在网络通信七层模型中,HTTP位于应用层,TCP/IP位于传输层。HTTP直接和TCP对接。
    • 以HTTPS通信时,形式为:HTTP(应用层) + SSL/TLS(会话层) + TCP/IP(传输层)。
    • SSL/TLS独立于HTTP与TCP/IP,是一个新的协议。

加密方法

  • 对称密钥加密。加密和解密共用一个密钥的方式。
    • 问题:密钥一旦被窃取,就没有意义
  • 非对称加密。两把钥匙:私有密钥 + 公开密钥。
    • 私有密钥自己留着用,不能让其他人知道,用于对信息解密。
    • 公开密钥任何人都可以获取,用于对信息加密。
    • 问题:密文接收方无法证明公开密钥本身就是货真价实的公开密钥。公开密钥在传输途中,真正的公共密钥已经被攻击者替换。
  • 第三方认证机构。用于证明公共密钥是值得信赖的。
    • 拥有数字证书的客户端可以使用绑定公钥证书的公开密钥。
    • 问题:认证机构颁发的认证证书也是可以被伪造的!

​ HTTPS采用的是对称加密和非对称加密两者并用的混合加密方式,因为对称加密相对于非对称加密的速度要快,对于通信双方的性能消耗较少。如果密钥能够实现安全交换,会优先采用对称加密否则为非对称加密。

SSL(Secure Socket Layer)和TLS(Transport Layer Security)

怎么理解HTTP + SSL/TLS = HTTPS中的SSL/TLS?SSL和TLS是一个东西吗?

  • SSL:安全套接层,TLS:安全传输层协议。
  • SSL技术最初由网景通信先倡导并开发的,后来主导权转移到IETF手中。
  • IETF以SSL3.0为基准,制定了TLS1.0、TLS1.1、TLS1.2
  • SSL为TLS的原型

SSL协议的问题:

  • 通信速度慢。使用SSL通信时需要对通信进行处理,做安全套阶层,导致延长通信时间,增加网络负载。
  • 消耗CPU、内存资源。由于HTTPS通信时需要做客户端和服务器双方的加密解密处理,会消耗CPU和内存等资源。

HTTP/2.0

​ 自从 HTTP/1.1以来,互联网由Web浏览器时代发展为移动互联网时代,发生翻天覆地的变化。但HTTP/1.1还有些许不完美,虽然HTTPS弥补了HTTP协议安全性不足的问题,但是一直为解决其传输效率的问题。

​ 随着时间的发展,大家对网络性能的期望也改变了——在 20 世纪 90 年代后期,大家愿意为一个页面等上 7 秒,而技术和市场调研公司 Forrester Research 在 2009 年的一项研究中发现,在线购物者期望单个页面能在 2 秒内完成加载,其中很大一部分用户会放弃加载时间超过 3 秒的页面。近期 Google 的一项研究表明,甚至 400 毫秒(一眨眼的时间)的延迟,都可能降低人们的搜索意愿。

​ 于是一个新的工种出现了:Web 性能专家,他们精于发掘变通办法,在原有协议上提升网页加载速度,我们现在所采用的多数Web性能优化手段就诞生于此。

​ 但这些优化手段治标不治本,只能说凑合。

​ 于是 HTTP/2.0 诞生了——该协议可以更好地适应如今的复杂页面,同时又不牺牲速度。 HTTP/2 可以使人们只需花很小的成本就可提高他们网站的感知性能。

​ 这里需要先补习一下SPDY协议,它是HTTP/2.0诞生的基础。

SPDY 协议

SPDY

​ 2009年Google的两位工程师 Mike Belshe 和 Roberto Peon 提出了一种弥补HTTP传输数据过程中各种不足的协议: SPDY(发音同 speedy)。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。据说用了这个协议后页面加载速度提高64%。SPDY主要就是为了解决传输速度数据安全性的问题。

这里再次回顾下HTTP的问题以便更好的理解SPDY协议:

  • 一条连接上只可以发送一个请求
  • 请求只能从客户端开始。客户端不可以接受除相应以外的指令。
  • 请求/响应首部未经压缩就发送。首部信息越多延迟越大。
  • 发送冗长的首部,每次相互发送相同的首部造成的浪费较多。
  • 可任意选择数据压缩格式。非强制压缩发送。

SPDY的特点:

  • 多路复用流。通过单一的TCP连接,可以无限制处理多个HTTP请求。所有的请求处理都在一条TCP连接上完成,TCP处理效率得到提高。
  • 赋予请求优先级。SPDY协议可以给请求逐个分配优先级顺序,解决在同时进行多个请求时,因为带宽低而导致的响应变慢问题。
  • 压缩HTTP首部。通过压缩HTTP请求和响应的首部,减少通信中产生的数据包数量和字节数。
  • 服务器推送功能。支持服务器主动向客户端推送数据的功能。服务器可以主动发送数据,不再需要等待客户端的请求。
  • 服务器提示功能。服务器可以主动提示客户端请求所需的资源。由于客户端发现资源之前就可以获知资源的存在,因此在资源已经缓存的情况下,可以避免发送不必要的请求。
  • 基于HTTPS的加密协议传输。 保留了HTTPS的TLS加密特性,大大提高了传输数据的可靠性。

头部压缩

HTTP/2.0

​ 谷歌设计使用SPDY协议的这套操作被互联网工程任务组IETF)盯上,并且发现这东西顶好,可以吸收进来,于是将SPDY协议进行了标准化后,在2015年5推出了类似于SPDY协议的 [HTTP 2.0](baike.baidu.com/item/HTTP 2.0) 协议标准(简称HTTP/2)。谷歌一看这都被整合到新的HTTP/2.0中了,我还维护它干什么,干嘛不直接使用HTTP/2.0,于是也就停止了对SPDY协议的继续维护与支持。

​ HTTP/2.0继承了SPDY协议的所有优点。

​ 启用HTTP/2.0后会给性能带来很大的提升,但同时也会带来新的性能瓶颈。因为现在所有的压力集中在底层一个TCP连接之上,TCP很可能就是下一个性能瓶颈,比如TCP分组的队首阻塞问题,单个TCP packet丢失导致整个连接阻塞,无法逃避,此时所有消息都会受到影响。

​ 未来,服务器端针对HTTP 2.0下的TCP配置优化至关重要。

HTTP/3.0

HTTP2.0虽然已经很优秀了,已经大大提高了传输数据速度,但是还有一些问题:

  • SPDY只是将单个域名的通信多路复用,如果一个Web网站使用了多个域名下的资源,其效果就会减弱。
  • HTTP是基于TCP建立可靠连接的,如果出现了丢包,那么整个连接都要等待重传,HTTP/1.1可以同时使用6个TCP连接,一个阻塞另外五个还能工作,但HTTP/2只有一个TCP连接,阻塞的问题便被放大了,可能使HTTP2.0的性能还不如HTTP1.1。
  • 现阶段需要进行优化的就TCP了。

2015年,Google这时候又出现了。Google看出了问题的本质,就是TCP协议:

  • 连接慢,必须三握四挥
  • 并不怎么可靠,可能导致丢包,丢包就得重来一遍
  • 想做到安全需要SSL/TLS加持

但是Google没有实力更改TCP协议,这个控制权不在他手上啊。于是Google基于UDP协议又创建了一套新的协议——QUIC协议。

基于QUIC协议创建了HTTP3.0。

QUIC协议针对HTTP2.0协议解决了下面的问题:

  • 0RTT减少TCP三次握手及TLS握手时间

  • 什么是RTT?RTTRound Trip Time的缩写,通俗地说,就是通信在服务器与客户端之间一来一回的时间。三次握手需要经过 一去(SYN) + 二回(SYN + ACK)+ 三去(ACK) = 1.5RTT。

0RTT

  • 多路复用

    • QUIC 原生实现了多路复用功能,并且传输的单个数据流可以保证有序交付且不会影响其它数据流,这样的技术就解决了前边提到的 TCP 多路复用存在的问题。同 HTTP/2 一样,同一个 QUIC 连接上可以创建多个 stream 来发送多个 HTTP 请求,但是,QUIC 是基于 UDP 的,因为一个连接上的多个 stream 之间没有依赖,所以不存在 HTTP/2 中的问题。
  • FEC前向纠错机制解决丢包问题

    • 每个数据包除了它本身的内容之外,还包括了该数据包前一个及后一个数据包的位置数据,因此少量的丢包可以通过其它包的数据直接组装而无需重传。
  • 更安全加密认证报文

    • TCP与HTTP的安全性是需要SSL/TLS的,但是采用QUIC的报文头和报文主体都是经过加密的。
  • 连接迁移。什么是连接迁移?

    • TCP连接基于四元组(源 IP、源端口、目的 IP、目的端口),切换网络时至少会有一个因素发生变化,导致连接发生变化。
    • 当连接发生变化时,如果还使用原来的 TCP 连接,则会导致连接失败,就得等原来的连接超时后重新建立连接,所以我们有时候发现切换到一个新网络时,即使新网络状况良好,但内容还是需要加载很旧。
    • QUIC 的连接不受四元组的影响,当这四个元素发生变化时,原连接依然维持。QUIC 连接不以四元组作为标识,而是使用一个 64 位的随机数,这个随机数被称为 Connection ID,对应每个stream,即使 IP 或者端口发生变化,只要 Connection ID 没有变化,那么连接依然可以维持。
  • 流量控制。 基于 stream 和 connection 级别的流量控制。

    • QUIC 支持多路复用。 Stream 可以认为就是一条 HTTP 请求。 Connection 可以类比一条 TCP 连接。多路复用意味着在一条 Connetion 上会同时存在多条 Stream。
    • 保障可以在内存不足或者上游处理性能出现问题时,通过流量控制来限制传输速率,保障服务可用性。

发展史

HTTP请求方法

  • GET 获取资源,用来请求访问已被URI识别的资源。
  • POST 传输实体主体,一般用于表单内容的提交。
  • PUT 传输文件
  • HEAD 获得报文首部,用于确认URI的有效性及资源更新的日期时间。
  • DELETE 删除文件
  • OPTIONS 询问支持的方法
  • TRACE 追踪路径,让Web服务器端将之前的请求通信返回给客户端的方法。
  • CONNECT 要求用隧道协议连接代理,要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信,主要使用SSL和TLS协议把通信内容加密后经网络隧道传输

面试题:GET方法与POST方法相比有什么区别?POST方法可以用来获取资源吗?

HTTP状态码

​ HTTP状态码最早出现在HTTP/1.0中,在后续的版本中有进行了完善。状态码主要表示客户端HTTP请求的返回结果、标记服务器端的处理状态是否正常、通知出现的错误等工作。

  • 状态码的类别
类别原因短语
1XX信息状态码(Informational)接受的请求正在处理
2XX成功状态码(Success)请求正常处理完毕
3XX重定向状态码(Redirection)需要进行附加操作以完成请求
4XX客户端错误状态码(Client Error)服务器无法处理请求
5XX服务端错误状态码(Server Error)服务器处理请求出错
  • 2XX 成功,响应结果表明请求被正常处理。
    • 200 OK,表示客户端发来的请求在服务器端被正常处理。
    • 204 No Concent,表示服务器接受的请求已成功处理,但在返回的响应报文中不含实体的主题部分。
    • 206 Partial Content,表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。
  • 3XX 重定向,表明浏览器需要执行某些特殊的处理以正确处理请求。
    • 301 Moved Permanently,永久性重定向,表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI
    • 302 Found ,临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户能使用新的URI访问。
    • 303 See Other,表示请求对应的资源存在着另一个URl,应使用GET方法定向获取请求的资源。
    • 304 Not Modified,表示客户端发送附带条件的请求时,服务端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304。
    • 307 Temporary Rediect,临时重定向。该状态码与302 Found 有着相同的含义。

301与302的比较:

  • 特点:都会跳转到新的URL,但是永久重定向的URL会被永久更改,二临时的只是临时的。
  • 缓存方面:临时重定向返回的资源不会被客户端缓存,永久重定向会资源会被重新缓存。
  • SEO方面:永久重定向的资源,会被浏览器爬虫记录,有利于SEO优化,而临时相反。
  • 4XX 客户端错误,响应结果表明客户端是发生错误的原因所在。
    • 400 Bad Request,该状态码表示请求报文中存在语法错误。
    • 401 Unauthorized,该状态码表示请求需要有通过HTTP认证的认证信息。
    • 403 Forbidden,该状态码表明请求资源的访问被服务器拒绝了。
    • 404 Not Found,表明服务器上无法找到请求的资源。
  • 5XX 服务器错误,表明服务器本身发生错误
    • 500 Internal Server Error,表明服务器端在执行请求时发生了错误
    • 503 Service Unavailable,表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

HTTP首部

HTTP首部负责客户端和服务端之间以HTTP协议进行通信时,对通信内容的约定描述重要信息的传递。

简单说:

就是对客户端与服务器之间通信过程的描述!

HTTP报文首部

报文首部

报文首部包含客户端和服务端处理时起至关重要作用的信息。

  • 报文结构:

    报文首部 + 空行 + 报文主体

​ HTTP协议的请求和响应报文中必定包含HTTP首部,首部内容为客户端和服务端分别处理请求和响应提供所需要的信息。

  • 请求行(请求报文首部):请求方法 + URI + HTTP版本

  • 状态行(响应报文首部):响应结果状态码 + 原因短语 + HTTP版本

  • 首部字段:请求和响应的各种条件和属性的各类首部,格式:

    首部字段名:字段值

响应报文

4中HTTP首部字段类型:

  • 通用首部字段(General Header Fields):请求报文和响应报文两方都会使用的首部
  • 请求首部字段(Request Header Fields):从客户端向服务器端发送请求报文时使用的首部。补充请求的附加内容、客户端信息、响应内容相关优先级等信息。
  • 响应首部字段(Response Header Fields):从服务器端向客户端返回响应报文时使用的首部。补充响应的附加内容,也会要求客户端附加额外的内容信息。
  • 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充资源内容更新时间等与实体有关的信息。

通用首部字段(General Header Fields)

  • Cache-Control,用以控制缓存的行为。
Cache-Control: private, max-age=0, no-cache

缓存请求指令:

指令参数说明
no-cache强制向源服务器再次验证
no-store不缓存请求或者响应的任何内容
max-age=[秒]必需响应的最大Age值
max-stale(=[秒])可省略接受已过期的响应
min-fresh=[秒]必需期望在指定时间内的响应仍有效
no-transform代理不可更改媒体类型
only-if-cached从缓存获取资源
cache-extension-新指令标记

缓存响应指令:

指令参数说明
public可向任意方提供响应的缓存
private可省略仅向指定用户返回响应
no-cache可省略缓存前必须先确认其有效性
no-store不缓存请求或相应的任何内容
no-transform代理不可更改媒体类型
must-revalidate可缓存但必须在向源服务器进行确认
proxy-revalidate要求中间缓存服务器对缓存的响应有效性在进行确认
⭐max-age=[秒]必需响应的最大Age值
s-maxage=[秒]必需公共缓存服务器响应的最大Age值
cache-extension-新指令标记

强缓存与协商缓存:

  • 强缓存:服务端告知客户端缓存时间后,由客户端判断并决定是否使用缓存。首次发起请求时,服务端会在Response Headers 中写入缓存新鲜时间。当请求再次发出时,如果缓存新鲜,将直接从缓存获取资源,而不会再与服务器发生通信。

  • 协商缓存:由服务端决定并告知客户端是否使用缓存。浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。

    传送门👉浅谈HTTP缓存

  • Connection
    • 控制不再转发给代理的首部字段
    • 管理持久连接
    • 在HTTP1.1中默认为Keep-Alive,当服务端想明确断开连接时,则需要将值设置为Close
Connection: close
// 或者
Connection: Keep-Alive
  • Date,表明创建HTTP报文的日期和时间
 Date: Sat, 10 Oct 2020 08:20:54 GMT
  • Pragma,HTTP1.0控制缓存的方式,历史遗留字段。
Cache-Control: no-cache // 最理想
Pragma: no-cache
  • Trailer,用于说明报文主体后记录了哪些首部字段。该首部字段可应用于HTTP/1.1版本分块传输编码时。
···
Transfer-Encoding: chunked
Trailer: Expires
···(报文主体)···
Expires: Sat, 10 Oct 2020 08:25:26 GMT
  • Transfer-Encoding,规定了传输报文主体时采用的编码方式
Transfer-Encoding: chunked
  • Upgrade,用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,可以用来指定一个完全不同的通信协议。
Upgrade: TLS/1.0
  • Via,为了追踪客户端和服务器之间的请求和响应报文的传输路径。
Via: cache8.cn414[52,0]
  • Warning,告知客户端与缓存相关的问题的警告

请求首部字段(Request Header Fields)

  • Accept,告知服务器,用户代理能够处理的媒体类型及媒体类型的优先级,type/subtypeq值为权重值,取值范围0~1
    • 文本文件
    • 图片文件
    • 视频文件
    • 应用程序使用的二进制文件
Accept: text/html,application/xhtml+xml;q=0.9,*/*;q=0.8
  • Accept-Charset,告知服务器,用户代理支持的字符集及字符集的相对优先顺序,可以使用q值来表示相对优先级
Accept-Charset: iso-8859-5,unicode-1.1;q=0.8
  • Accept-Encoding,告知服务器,用户代理支持的内容编码及内容编码的优先级顺序。
    • gzip
    • compress
    • deflate
    • identity
Accept-Encoding: gzip, deflate, br
  • Accept-Language,告知服务器,用户代理能够处理的自然语言集,以及自然语言集的相对优先级。
Accept-Language: zh-CN,zh;q=0.9
  • Authorization,告知服务器,用户代理的认证信息
Authorization: Basic emhzZjp6aHNmNjY2Ng==
  • Expect,告知服务器,期望出现的某些特定行为
  • From,告知服务器,使用用户代理的用户电子邮件地址。其实就是要知道用户代理的负责人的联系方式
  • Host,告知服务器,请求的资源所处的互联网主机名和端口号
  • If-Match,告知服务器,需要满足请求的条件,只有当If-MatchEtag值匹配一致时,服务器才会接受请求
If-Match: "1123sdfsdf"
  • If-Modified-Since,告知服务器,如果资源的更新时间早于该字段值,则希望处理该请求
If-Modified-Since: Sat, 10 Oct 2020 09:04:19 GMT
  • If-None-Match,告知服务器,当If-MatchEtag值匹配不一致时,服务器才会接受请求
If-None-Match: none
  • If-Range,告知服务器,当请求资源的Etag值或者时间与该字段值相一致时,则作为范围请求处理。否则返回全体资源
If-Range: "sdfs12123"
  • If-Unmodified-Since,与If-Modified-Since作用相反,告知服务器指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求
If-Unmodified-Since: Sat, 10 Oct 2020 09:04:19 GMT
  • Proxy-Authorization,接收到从代理服务器发来的认证质询时,客户端会发送包含该首部字段的请求,已告知服务器认证所需要的信息。
Proxy-Authorization: Basic emhzZjp6aHNmNjY2N
  • Range,只获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。
Range: bytes=5001-10000
  • Referer(Referrer),告知服务器,请求的原始资源的URI
Referrer: https://baidu.com/
  • TE,告知服务器,客户端能够处理响应的传输编码方式及相对优先级
  • User-Agent,会将创建请求的浏览器和用户代理名称等信息传达给服务器

响应首部字段(Response Header Fields)

  • Accept-Ranges,告知客户端,服务器是否能以处理范围请求,以指定获取服务器端某个部分的资源
Accept-Ranges: bytes
  • Age,告知客户端,源服务器在多久前创建了响应,单位[秒]
Age: 900
  • ETag,告知客户端,实体标识,是一种可以将资源以字符串形式做唯一性的标识
    • 强ETag值,不论实体发生多么细微的变化都会改变其值
    • 弱ETag值,只用于提示资源是否相同,只有资源发生根本改变,才会改变,以W/开头
// 强
ETag: "usagi-1234"
// 弱
ETag: W/"usagi-1234"
  • Location,配合3XX重定向的响应,提供重定向的URI
Location: https://www.userdesign/user/413072104370941.html
  • Proxy-Authenticate,将由代理服务器所要求的认证信息发送给客户端
  • Retry-After,告知客户端,应该多久之后再次发送请求
Retry-After: 200
  • Serve,告知客户端当前服务器上安装的HTTP服务器应用程序的信息
  • Vary,对缓存进行控制
  • WWW-Authenticate,用于HTTP方位认证

实体首部字段(Entity Header Fields)

  • Allow,告知客户端,服务端能够支持Request-URI指定资源的HTTP方法
Allow: GET, OPTIONS, HEAD, PUT, POST
  • Content-Encoding,告知客户端,服务端对实体的主体部分选用的内容编码方式
    • gzip
    • compress
    • deflate
    • identity
Content-Encoding: gzip
  • Content-Language,告知客户端,实体主体使用的自然语言
Content-Language: zh-CN
  • Conent-Length,表明实体主体部分的大小(单位是字节)
Conent-Length: 19000
  • Content-Location,给出与报文主体部分相对应的URI
Content-Location: http://www.hacker.jp/index-ga.html
  • Content-MD5,一串由MD5算法生成的值,其目的在于检查主体在传输过程中是否保持完整,以及确认传输到达
Content-MD5: SDFJHdsKJHS23dsSDFSDFdsDSFds7623==
  • Content-Range,告知客户端,作为响应返回的尸体的哪个部分符合范围请求
Content-Range: 5001-10000/10000
  • Content-Type,说明实体主体内对象的媒体类型,与Accept相同
  • Expires,将资源的失效的日期告知客户端,优先级低于Cache-Control指定的max-age指令
Sat, 10 Oct 2020 09:03:28 GMT
  • Last-Modified,指明资源最终修改的时间
Last-Modified: Sat, 10 Oct 2020 09:03:28 GMT

Cookie

负责客户端和服务器之间状态管理及用户识别。

  • Set-Cookie,响应首部字段,当服务端准备开始管理客户端的状态时,回事先告知各种信息。
    • expires属性用于指定浏览器可发送Cookie的有效期
    • path属性用于限制指定Cookie的发送范围的文件目录
    • domain属性指定的域名可做到与结尾匹配一致(不指定更安全)
    • secure属性用于限制Web页面仅在HTTPS安全连接时,才可以发送Cookie
    • HttpOnly属性可使JavaScript无法获得Cookie。主要是为了防止跨站脚本攻击对Cookie的窃取
 Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
  • Cookie,请求首部字段,服务器接收到的Cookie信息,告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。
cookie: _ga=GA1.2.738440178.1603459806; MONITOR_WEB_ID=4d42d1f2-6f1e-4c48-b667-37cdfgfd23184; 

HTTP内容

Web安全

主动攻击

攻击者通过直接访问Web应用,把攻击代码传入的攻击模式,直接针对服务器上的资源进行攻击。

⭐SQL注入攻击

​ SQL注入通常是指,攻击者直接将非法的SQL语句注入数据库中,从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统用户最高权限。

特点:

  • 非法查看或者篡改数据库内的数据
  • 规避认证
  • 执行和数据库服务器业务相关的程序

防御:

  • 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。

  • 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。

  • 转义字符。对进入数据库的特殊字符(',",\,<,>,&,*,; 等)进行转义处理,或编码转换。基本上所有的后端语言都有对字符串进行转义处理的方法,比如 lodash 的 lodash._escapehtmlchar 库。

  • 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。例如 Node.js 中的 mysqljs 库的 query 方法中的 ? 占位参数。

OS命令注入攻击

​ OS命令注入是指攻击者通过Web应用,执行非法的操作系统命令达到攻击的目的,这里直接针对的是操作系统。当可以从Web应用中通过Shell来调用操作系统命令时,如果这时调用Shell时存在疏漏,就可以执行插入的非法OS命令。

被动攻击

攻击者利用圈套策略执行攻击代码的攻击模式,攻击者不直接对目标Web应用访问发起攻击。

⭐XSS(Cross-SIte Scription,XSS)跨站脚本攻击

​ 通常指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签和Javascript ,篡改网页,插入恶意脚本,然后在用户浏览网页时,控制用户浏览器(盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害)的一种攻击方式。

特点:

  • 利用虚假输入表单骗取用户个人信息
  • 利用脚本窃取用户Cookie,在被害者不知情的情况下,发送恶意请求
  • 显示伪造的文章或者图片

防御:

  • 开启CSP。CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。
  • 转移字符。用户的输入永远不可信任的,最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义。
  • HttpOnly。可以避免该网页的cookie被客户端恶意JavaScript窃取,保护用户cookie信息。

HTTP首部注入攻击

攻击者通过在响应首部字段内插入换行,添加任意响应首部或者主体的一种攻击。

影响:

  • 设置任何Cookie信息
  • 重定向至任意URL
  • 显示任意的主体(HTTP响应截断攻击)

⭐CSRF跨站点请求伪造

通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息和设定信息等某些状态更新。

简单说,就是攻击者通过获取你的身份,来访问服务器,并进行一些恶意操作。

利用以通过认证的用户权限:

  • 更新设定信息
  • 购买商品
  • 在留言板上发表评论

防御:

  • 验证码
  • Referer Check
  • Anti CSRF Token
  • SameSite

会话劫持

通过某种手段获取到用户的会话ID,并非法使用此会话ID伪装成用户,达到攻击目的。

攻击者获取会话ID途径:

  • 通过非正规的生成方法推测会话ID
  • 通过窃听或者XSS攻击盗取会话ID
  • 通过会话固定攻击强行获取会话ID

点击劫持

攻击者利用透明的按钮或者链接做成陷阱,覆盖在Web页面之上。诱导用户在不知情的情况下,点击攻击链接的一种手段

通过页面伪装,在用户进行操作过程中,通过点击透明的按钮或者遮罩层,发起请求。

防御

  • X-FRAME-OPTIONS。X-FRAME-OPTIONS是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击。该响应头有三个值可选,分别是
    • DENY,表示页面不允许通过 iframe 的方式展示
    • SAMEORIGIN,表示页面可以在相同域名下通过 iframe 的方式展示
    • ALLOW-FROM,表示页面可以在指定来源的 iframe 中展示

面试题

  • HTTP常见状态码的含义?
  • HTTP请求方法列举?
  • ⭐POST请求和GET请求的比较?
  • HTTP的特点、缺点?
  • ⭐HTTP缓存相关问题:强缓存与弱缓存?
  • ⭐状态码301302的区别?
  • ⭐常见Web攻击方式及防御方法
  • 列举几个你知道的HTTP首部字段及作用

钱当然很重要,这我不是不知道;我一天何尝不为钱而受熬苦!可是,我又觉得,人活这一辈子,还应该有些另外的什么才对……—— 路遥

参考文献: