HTTP/HTTPS-总结与心得

359 阅读15分钟

前言

HTTP好比互联网中各种资源的搬运工,作为程序员的我们(不管你是哪方面的开发人员)都或多或少地会与其打交道,不管是在工作中还是面试中,我们都能看到它们的身影,所以HTTP的重要性不言而喻。前不久一个朋友在参加大大小小的面试中,基本上每个面试官都会问到,然后他跟我吐槽http知识点太多记不住。于是就有了这篇文章,在我的草稿箱里躺了一个多月才得以面世(ps:不知如何开头,然后各种事情...)!

HTTP/HTTPS相关知识点

TCP/IP

应用层

应用层决定了向用户提供应用服务时通信的活动。

传输层

传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。

网络层(网路互联层)

网络层用来处理在网络上流动的数据包,数据包是网络传输的最小数据单位,改层规定了通过怎样的路劲(所谓的传输路线)到达对方计算机,并把数据包传送给对方。

链路层(数据链路层,网络接口层)

用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、网卡、光纤等等,硬件上的范畴均在链路层的作用范围。

重点聊一下DNS、TCP、UDP(敲黑板、划重点):

DNS协议

用户通常通过使用主机名或者域名来访问对方的计算机,而不是通过IP地址访问,所以DNS协议应运而生,提供提供域名到服务器IP地址之间的解析服务。

注:摘抄自《图解HTTP》(偷个懒。。。)

TCP协议

TCP协议提供可靠的字节流服务,可以将大块数据分割成报文段为单位的数据包进行管理,能够准确可靠地将数据传递给对方,为了准确无误地将数据送到目标处,TCP协议采用了三次握手策略。

注:摘抄自《图解HTTP》,此图画出了我的心声

发送端首先发送一个带SNY标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示创达确认信息,最后发送端再回传一个带ACK标志的数据包,代表连接过程结束。

UDP协议

UDP协议与TCP协议一样用于处理数据包,不同的是:在传送数据前不需要先建立连接,正是因为如此,省去和很多的开销,使得它的速度比较快,一些对实时性要求较高的服务,通常使用的就是UDP协议。

PS:其它协议我就不码字了,问下度娘可以加深印象^_^

HTTP协议

http协议处于应用层,用于客户端与服务端之间的通信,不保存状态。所以Cookie就诞生了~

Cookie

HTTP是无状态协议,他不对之前发生过的请求和响应的状态进行管理,无法根据之前的状态进行本次的请求处理。 举个栗子:假设要求登录认证的web页面本身无法进行状态的管理,现在有100个客户端,分别向服务器端发送请求,服务器无法辨别对应的客户端,每次都需要客户端重新登录。

注:摘抄自《图解HTTP》,画的太好了~

我们来看看开发中实际的报文: 1、第一次请求(请求报文中-没有Cookie信息状态)

我们再来看看响应报文:

服务器端生成了Cookie信息 2、后面的数据请求(请求报文中-都会带上Cookie信息)

sessionId

一般用来标记用户,session保存在服务端,而sessionId通过存放在cookie中来传输,sessionId在服务器端产生对应着登陆的用户。

HTTP报文

http请求报文

举个栗子(百度首页):

报文首部信息字段含义,稍后详解

http响应报文

首部字段

http1.1规范了47种首部字段 通用首部字段

请求首部字段
响应首部字段
实体首部字段

浏览器缓存机制

敲黑板、划重点

强缓存

强缓存是利用 http 头中的 Expires 和 Cache-Control 两个字段来控制的。强缓存中,当请求再次发出时,浏览器会根据其中的 expires 和 cache-control 判断目标资源是否“命中”强缓存,若命中返回的 HTTP 状态码为200则直接从缓存中获取资源,不会再与服务端发生通信。

Cache-Control 相对于 expires 更加准确,它的优先级也更高。当 Cache-Control 与 expires 同时出现时,我们以 Cache-Control 为准。

expires 是一个时间戳,接下来如果我们试图再次向服务器请求资源,浏览器就会先对比本地时间和 expires 的时间戳,如果本地时间小于 expires 设定的过期时间,那么就直接去缓存中取这个资源。

从这样的描述中大家也不难猜测,expires 是有问题的,它最大的问题在于对“本地时间”的依赖。如果服务端和客户端的时间设置可能不同,或者我直接手动去把客户端的时间改掉,那么 expires 将无法达到我们的预期。

考虑到 expires 的局限性,HTTP1.1 新增了 Cache-Control 字段来完成 expires 的任务。 expires 能做的事情,Cache-Control 都能做;expires 完成不了的事情,Cache-Control 也能做。因此,Cache-Control 可以视作是 expires 的完全替代方案。 现在我们给 Cache-Control 字段一个特写:

如大家所见,在 Cache-Control 中,我们通过 max-age 来控制资源的有效期。max-age 不是一个时间戳,而是一个时间长度。在本例中,max-age 是 2592000 秒,它意味着该资源在 2592000 秒以内都是有效的,完美地规避了时间戳带来的潜在问题。

Cache-Control 应用分析

Cache-Control 的神通,可不止于这一个小小的 max-age。如下的用法也非常常见:

s-maxage 优先级高于 max-age,两者同时出现时,优先考虑 s-maxage。如果 s-maxage 未过期,则向代理服务器请求其缓存内容。

这个 s-maxage 不像 max-age 一样为大家所熟知。的确,在项目不是特别大的场景下,max-age 足够用了。但在依赖各种代理的大型架构中,我们不得不考虑代理服务器的缓存问题。s-maxage 就是用于表示 cache 服务器上(比如 cache CDN)的缓存的有效时间的,并只对 public 缓存有效。

public 与 private

public 与 private 是针对资源是否能够被代理服务缓存而存在的一组对立概念。

如果我们为资源设置了 public,那么它既可以被浏览器缓存,也可以被代理服务器缓存;如果我们设置了 private,则该资源只能被浏览器缓存。private 为默认值。但多数情况下,public 并不需要我们手动设置,比如有很多线上网站的 cache-control 是这样的:

设置了 s-maxage,没设置 public,那么 CDN 还可以缓存这个资源吗?答案是肯定的。因为明确的缓存信息(例如“max-age”)已表示响应是可以缓存的。

no-store与no-cache

no-cache 绕开了浏览器:我们为资源设置了 no-cache 后,每一次发起请求都不会再去询问浏览器的缓存情况,而是直接向服务端去确认该资源是否过期(即走我们下文即将讲解的协商缓存的路线)。

no-store 比较绝情,顾名思义就是不使用任何缓存策略。在 no-cache 的基础上,它连服务端的缓存确认也绕开了,只允许你直接向服务端发送请求、并下载完整的响应。

协商缓存

协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。

如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是 304(如下图)。

Last-Modified 与 Etag

Last-Modified 是一个时间戳,如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回:

随后我们每次请求时,会带上一个叫 If-Modified-Since 的时间戳字段,它的值正是上一次 response 返回给它的 last-modified 值:

服务器接收到这个时间戳后,会比对该时间戳和资源在服务器上的最后修改时间是否一致,从而判断资源是否发生了变化。如果发生了变化,就会返回一个完整的响应内容,并在 Response Headers 中添加新的 Last-Modified 值;否则,返回如上图的 304 响应,Response Headers 不会再添加 Last-Modified 字段。

使用 Last-Modified 存在一些弊端,这其中最常见的就是这样两个场景:

1、我们编辑了文件,但文件的内容没有改变。服务端并不清楚我们是否真正改变了文件,它仍然通过最后编辑时间进行判断。因此这个资源在再次被请求时,会被当做新资源,进而引发一次完整的响应——不该重新请求的时候,也会重新请求。 2、当我们修改文件的速度过快时(比如花了 100ms 完成了改动),由于 If-Modified-Since 只能检查到以秒为最小计量单位的时间差,所以它是感知不到这个改动的——该重新请求的时候,反而没有重新请求了。

这两个场景其实指向了同一个 bug——服务器并没有正确感知文件的变化。为了解决这样的问题,Etag 作为 Last-Modified 的补充出现了

Etag 是由服务器为每个资源生成的唯一的标识字符串,这个标识字符串是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的,反之亦然。因此 Etag 能够精准地感知文件的变化。 Etag 和 Last-Modified 类似,当首次请求时,我们会在响应头里获取到一个最初的标识符字符串,它可以是这样的:

那么下一次请求时,请求头里就会带上一个值相同的、名为 if-None-Match 的字符串供服务端比对了:

Etag 的生成过程需要服务器额外付出开销,会影响服务端的性能,这是它的弊端。因此启用 Etag 需要我们审时度势。正如我们刚刚所提到的——Etag 并不能替代 Last-Modified,它只能作为 Last-Modified 的补充和强化存在。 Etag 在感知文件变化上比 Last-Modified 更加准确,优先级也更高。当 Etag 和 Last-Modified 同时存在时,以 Etag 为准。

HTTPS

一张图告诉你区别:

HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL(Secure Socket Layer) 和TLS(Transport Layer Security)协议代替而已,SSL与TLS在传输层与应用层之间对网络连接进行加密。 SSL/TLS:是为网络通信提供安全及数据完整性的一种安全协议. SSL:采用公开密钥加密(非对称加密算法)的处理方式来保证网络通信的安全,公开密钥加密使用一对非对称的密钥,一把叫做公开密钥,另一把叫私有密钥。

HTTP状态码

状态码:当客户端向服务器端发送请求时,描述返回的请求结果,用户可以根据状态码判断服务器是正常处理了请求还是出现了错误。 状态码类别如下:

注:具体的状态码,这里就不一一列举了...

HTTP版本

上面提到的HTTP都是基于HTTP1.1(目前使用最广泛的版本)

HTTP/2.0

HTTP2.0基于SPDY,主要是改善了数据传输的性能和安全性!

  • 二进制编码:请求数据与相应数据采用二进制编码,分割成多个帧进行传输,效率更高
  • 报文首部压缩:报文首部采用“HPACK”算法,在客户端和服务端两端建立“字典”,用索引号表示重复的字符串,对于相同的数据,不用重复请求和相应发送,减少冗余数据;采用哈夫曼编码压缩整数和字符串,可以达到50%~90%的压缩率。
  • 多路由复用:同域名下所有通信都是在单个连接上完成,单个连接可以承载任意数量的双向数据流

HTTP/2.0:

HTTP/2 的缺点:

  • TCP以及TCP+TLS建立连接开销 1、建立TCP连接需要和服务器进行三次握手来确认连接成功,需要消耗1.5个RTT之后才能进行数据传输. 2、进行TLS连接,TLS有两个版本——TLS1.2和TLS1.3,每个版本建立连接所花的时间不同,大致是需要1~2个RTT.

  • TCP的队头阻塞问题 TCP为了保证可靠传输,有个“丢包重传”机制,丢失的包必须要等待重新传输确认,HTTP/2出现丢包时,整个TCP 都要开始等待重传。

HTTP/3.0

由于HTTP/2.0的缺陷,Google在推SPDY的时候就已经意识到了这些问题,于是就有了基于 UDP协议的“QUIC”协议,让HTTP跑在QUIC上而不是TCP上。它在HTTP/2的基础上又实现了质的飞跃,真正“完美”地解决了“队头阻塞”问题。 QUIC协议:

  • QUIC在UDP的基础之上增加了一层来保证数据可靠性传输,提供了数据包重传、拥塞控制以及其他一些TCP中存在的特性
  • QUIC可以实现使用0-RTT或者1-RTT来建立连接,这意味着QUIC可以用最快的速度来发送和接收数据
  • QUIC实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输,就解决了TCP中队头阻塞的问题

网络安全-Web攻击类型

SQL注入攻击与OS命令注入攻击

a、攻击者设置好攻击连接,引诱用户触发连接 b、执行恶意代码后,用户所持有的Cookie被窃取,用户权限被恶意使用 c、执行攻击命令操作服务器上数据资源 防护策略: 1、不要使用动态SQL:避免将用户提供的输入直接放入SQL语句中;最好使用准备好的语句和参数化查询,这样更安全。 2、限制数据库权限和特权:将数据库用户的功能设置为最低要求;这将限制攻击者在设法获取访问权限时可以执行的操作 3、不要将敏感数据保留在纯文本中,加密存储在数据库中的私有/机密数据

跨站脚本攻击(XSS)

通过存在安全漏洞的Web网站注册用户浏览运行非法的HTML标签或JavaScript进行攻击。最常见的攻击之一:在提交的表单里输入非法脚本进行攻击。 防护策略: 对提交的所有内容和url中的参数进行过滤,过滤掉特殊字符,然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。

跨站点请求伪造(CSRF)

攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

典型的攻击流程:

  • 受害者登录a.com,并保留了登录凭证(Cookie)。

  • 攻击者引诱受害者访问了b.com。

  • b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie。

  • a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。

  • a.com以受害者的名义执行了act=xx。

  • 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。 防护策略:

  • 同源检测:阻止不明外域的访问

  • 提交时要求附加本域才能获取的信息(CSRF Token)

会话劫持

攻击者通过某种手段拿到了用户的会话ID,并使用此会话ID伪装成用户,到达攻击目的。

防护策略:

  • 设置HttpOnly:通过设置Cookie的HttpOnly为true,可以防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击
  • 加入Token校验:用于检测请求的一致性

总结

通过思维导图、流程图的形式将基础知识点串联成面,形成自己的知识体系。码字不易,望朋友们随手点个赞,谢谢~ (PS:HTTP的知识点实在是太多了,仅靠一篇文章做到面面俱到不太现实)

参考书籍或文章

  • 图解HTTP
  • 前端性能优化原理与实践
  • 解读HTTP/2与HTTP/3 的新特

转载请注明出处,商用请征得作者本人同意,谢谢!!!