送给前端er一份HTTP基础知识

前言

你们好,我是图图。也有一个多月没有写文章了。因为各类缘由,被迫提桶,真是艰难。通过几轮的面试以后,被面试官虐得惨惨的,其中许多缘由是没有仔细的学过 HTTP 的知识,我对这块的知识相对来讲比较薄弱,因此决定把数据结构和算法得先放一放了。因此把 HTTP 的知识学一遍,而后再补一下JS的基础。css

下面废话很少说,咱们开始吧!html

HTTP 是什么

HTTP是一种超文本传输协议,用于完成客户端和服务器端等等一系列的运做流程。而协议指的是规则的约定。能够说,Web 是创建在 HTTP 协议上进行通讯的。面试

HTTP的诞生

我相信你们也是这样,在学一门技术以前都会去了解一下它的历史,下面来看看 HTTP 的发展史。算法

HTTP 诞生于 1989 年 3 月。是一个名叫蒂姆伯纳斯-李的哥们儿提出的,最初设想的基本理念是:借助多文档之间相互关联造成的超文本,连成可相互参阅的 WWW(World Wide Web,万维网)。简称 Web。json

HTTP 0.9 在 1990 年问世。那时候的 HTTP 尚未做为正式的标准被创建。浏览器

HTTP 1.0 在 1996 年 5 月 正式做为标准。该协议标准如今仍然被普遍使用在服务器端。缓存

HTTP 1.1 在 1997 年 1 月公布为当前主流的 HTTP 协议版本。安全

HTTP 2.0 在 2012 年 3 月 征集建议。性能优化

HTTP 2.0 在 同年的 9 月份 发布了第一个草案。服务器

HTTP 2.0 在 2014 年 11 月实现了标准化。

了解 TCP/IP

在理解 HTTP 以前,咱们先简单的来了解一下 TCP/IP 协议族。通常使用的网络都是在 TCP/IP 协议的基础上运做的,而 HTTP 属于它内部的一个子集。

TCP/IP 协议族

在计算机和网络设备进行互相通讯时,双方都必须基于相同的方法。好比,如何探测到通讯目标,是哪边先发起通讯、用什么语言进行通讯、怎样结束通讯等等一些规则都是先要肯定好的。不一样的硬件、操做系统之间的通讯,全部的这一切都须要一种规则。而这种规则称为协议

协议中包括:从电缆的规格到 IP 地址的选定方法、寻找异地用户的方法、双方创建通讯的顺序,以及 Web 页面显示要处理的步骤,等等。将这些相关联的协议集合起来总称为 TCP/IP。

TCP/IP 模型各层做用

TCP/IP 重要的点就是分层。有如下4层:应用层、传输层、网络层和数据链路层

TCP四层.png

下面来介绍各层的做用。

  • 应用层:应用层决定了向用户提供应用服务时通讯的活动。好比,FTP(文件传输协议)和 DNS(域名解析系统)。HTTP 协议也在该层。

  • 传输层:传输层对上层应用层,提供处于网络链接中的两台计算机之间的数据传送。该层有两个不一样的协议:TCP 传输控制协议和 UDP 用户数据协议。

  • 网络层:网络层用来处理在网络上的数据包。数据包是网络传输的最小数据单位。网络层的做用就是在多条路线中选出一条传输路线进行数据传输。

  • 链路层:用来处理链接网络的硬件部分。包括什么操做系统、硬件的设备、什么路由器啊之类的等等,都属于该层。

TCP/IP 层次化的好处是:若是互联网由一个协议统一规划,某个地方须要改变设计时,就必须将全部部分总体替换掉。而分层以后只须要把变更的层替换掉。把各层之间的接口部分规划好以后,每层内部的设计就能够自由改动。好比,处于应用层上的应用能够只考虑分配给本身的任务,不用去考虑其余的问题。

TCP/IP 通讯传输流

TCP/IP 协议进行通讯时,会经过分层顺序和对方进行通讯。客户端从应用层往下走,服务器端则从链路层往上走。看下面的图。

1.3.1.jpg

  1. 首先客户端在应用层发出一个 HTTP 请求。
  2. 接着,在传输层接收到应用层的数据后进行分割,给每一个报文打上标记序号以及端口号转发给网络层。
  3. 在网络层,添加通讯目的地的 MAC 地址后转发给链路层。
  4. 接收端(也叫服务器端)的服务器在链路层接收到数据,按次序向上层发送,一直到应用层。传输到应用层才算真正接收到客户端发过来的 HTTP 请求。

和HTTP相关的协议

在HTTP客户端向服务器端发送报文以前,须要用到 IP、TCP、DNS 这三个和 HTTP 密不可分的协议。

IP 网络协议

IP(Internet Protocol)网络协议处于网络层。IP协议的做用是把各类数据包传送给对方。但要保证正确的传送给对方,其中两个重要的条件是 IP 地址和 MAC 地址。能够把它想象成你家的地址,或者说你的电话号码。

IP 地址指的是节点被分配到的地址,MAC 地址指的是网卡所属的固定地址。IP 地址能够跟 MAC 地址进行配对。IP 地址是可变的,MAC 地址是不可变的。

IP 和 IP地址别搞混了,IP是一种协议。而IP地址是则是每台计算机的标识

ARP 协议

IP 间的通讯依赖 MAC 地址。在网络上通讯的双方不多会在同一个局域网,通常都是通过多台计算机或者网络设备中专才能链接到对方。而在中转的过程当中,会利用下一站中转设备的 MAC 地址进行搜索下一个中转目标。而这时,会用到ARP协议ARP协议是一种用来解析地址的协议,经过通讯方的 IP 地址就能反查出对应的 MAC 地址

在到达通讯目标前的中转过程当中,计算机和路由器只能获取粗略的传输路线,这种机制叫作路由选择。

就跟你在淘宝上买东西是同样的道理。好比,你在淘宝网买了件衣服,快递公司会根据你的地址进行送货,在送货这个过程当中,并非直接送到你手里。而是通过各类什么杭州中转站而后又到深圳中转站,以后才送到你手里。

TCP 协议

TCP 协议处于传输层,主要的做用是提供可靠的字节流服务。字节流服务指的是,为了方便传输,将大块的数据分割成以报文段为单位的数据包进行管理。而可靠性的传输服务指的是,可以把数据准确可靠的传给对方。

为了准确的将数据传送给对方,三次握手就出现了。下图展现这个过程。

1.4.1.jpg

  1. 第一次握手:客户端先发送一个带 SYN 标志的数据包给对方。
  2. 第二次握手:服务器端收到以后,回传一个带有 SYN/ACK 标志的数据包表示传达确认信息。
  3. 第三次握手:最后,客户端再传回一个带 ACK 标志的数据包,表示 “握手” 结束。

DNS 服务

DNS 服务和 HTTP协议同样,处于应用层。它主要的做用是,将域名解析成 IP 地址。DNS 协议能够经过域名查找 IP 地址,也能够经过 IP 地址反查域名的服务。 1-5-1.jpg

下面展现每一个协议和HTTP协议的关系。 1-6-1.jpg

什么是URL和URI?

  • URL指的是统一资源定位符,是访问Web网站须要输入的网站地址。例如,http://www.tutu.com
  • URI指的是统一资源标识符,全称为Uniform Resource Identifier,它的做用是区分互联网中的不一样资源。好比,HTML 文档、图像、视频片断、程序等等。而 URLURI 的一个子集。

URI格式

下图展现了 URI 的格式。

URI.jpg

  • 协议名http:https:表示协议名称。不区分字母大小写,最后加上//
  • 登陆信息user:pass@ 表示获取服务器资源的用户和密码。但不推荐使用,由于不安全。
  • 服务器地址:服务器地址有三种:
    • 以域名的形式www.tutu.com;
    • 以 IPv4 192.168.0.1地址名;
    • [0:0:0:0:0:0:1]这种方括号括起来的 IPv6 地址;
  • 服务器端口号:8080表示端口号。
  • 文件路径/html/index.html表示服务器文件路径,资源的访问位置。
  • 查询字符串?userId=1表示文件路径中的参数。?后面以key=value的形式。若是后面还须要加参数,用&拼接。
  • 片断标识符#cn1表示文件中的某个位置。就是平时的网页锚点定位。

HTTP基础

HTTP 是一种无状态的协议,对发送过的请求/响应都不作持久化处理。

持久化链接

HTTP 1.1 中的全部链接都是默认开启的(keep-alive)。经过请求/响应头部的Connection字段能够查看是否开启持久化链接(后面会介绍该字段的值),而在 HTTP1.0中是默认关闭的(close)。

它的特色是,无论是客户端仍是服务器端,只要其中的一端没有提出断开链接,那么就会保持 TCP 链接。好处是,减小 TCP 链接的重复创建和断开链接形成的额外开销,减轻服务器压力。这样使得 HTTP 请求和响应速度更快结束,也提升页面的显示速度。

管线化

管线化是不用等待响应就能够发送下一个请求,也就是并行处理。不用一个接一个的等待响应,管线化比持久化链接还要更快。

HTTP 报文

HTTP 一共有两种报文:请求报文、响应报文。报文又分为报文头部和报文主体,报文主体是可选的。报文包含了如下三个部分。

  • 起始行start line)有如下两种类型。
    • 请求行:请求的方法、请求的 URL、HTTP的版本
    • 响应行:HTTP 版本、状态码
  • 头部字段header):一些头部信息,以key: value的形式。
  • 主体body):被发送的数据。

报文主体.jpg

这张图是以请求报文为例。

HTTP 的请求方法

  • GET:获取服务器资源。
  • POST:提交信息给服务器。
  • PUT:传输文件。
  • HEAD:和 GET 方法同样。可是只返回响应头部。做用是肯定 URL 的有效性和资源更新的时间。
  • DELETE:删除指定的资源。
  • OPTIONS:查询请求服务器指定的资源所支持的方法。
  • TRACE:用来确认链接过程当中发生的一些操做。
  • CONNECT:创建链接渠道,用于代理服务器。

HTTP 状态码

1xx

1XX表示接收的请求正在处理。

2xx 成功

  • 200 OK:表示客户端发送的请求在服务器端被正常处理了。
  • 204 No Content:表示请求被处理成功,但没有资源可返回。
  • 206 Partial Content:表示客户端只获取文件的一部份内容,而服务器成功执行了这部分的GET请求。响应报文中含Content-Range指定部分的实体内容。

3xx 重定向

  • 301 Moved Permanenty:永久重定向。表示请求的资源已经被分配了新的 URL,之后就使用资源如今所指的 URL。
  • 302 Found:临时重定向。表示请求的资源被分配了新的 URL。
  • 303 See Other:表示请求的资源存着另外一个 URL,应该用GET方法获取请求的资源。
  • 304 Not Modified:表示请求已经找到,但不符合条件请求。协商缓存就会返回这个状态码。
  • 307 Temporary Redirect:临时重定向,和302相似。可是补鞥呢改变请求方法。

当30一、30二、303响应状态码返回时,几乎全部浏览器都会将POST改成GET,并删除请求报文中的主体,以后请求会自动再次发送。30一、302标准是禁止把POST改为GET的,但实际使用的时候你们都会这么作。

4xx 客户端错误

  • 400 Bad Request:表示请求报文中存在语法错误。
  • 401 Unauthorized:表示发送的请求要经过 HTTP 认证的认证消息。若是以前请求过一次,就表示用户认证失败。
  • 403 Forbidden:表示对请求资源的访问被服务器拒绝。
  • 404 Not Found:表示服务器上没法找到请求的资源。

5xx 服务器错误

  • 500 Internal Serve Error:表示服务器端在执行请求时发生错误。
  • 503 Service Unavailable:表示服务器暂处于超负荷或者正在进行停机维护。

和HTTP相关Web服务器

HTTP进行通讯时,除了客户端和服务器端这两个以外,还有一些用于通讯数据转发的应用程序。例如代理、网关、隧道和缓存

代理

代理是一种具备转发功能的应用程序,它存在于客户端和服务器端之间,至关于一个中间人。它将客户端发送过来的请求并转发给服务器端。固然,它也会将服务器端返回的响应转发给客户端。

代理服务器.jpg

每次经过代理服务器转发请求或响应时,头部都会出现Via这个字段。

网关

网关是一种特殊的服务器,做为其余服务器的中间实体使用。用于将 HTTP 请求转化成其余协议通讯。网关接收请求时就好像本身的资源的源服务器同样对请求作处理。

网关.jpg

隧道

隧道是可按要求创建一条和其余服务器的通讯线路,到时候使用 SSL 加密进行通讯。隧道的目的是保证客户端和服务器进行安全的通讯。

隧道.jpg

缓存

缓存是指代理服务器或客户端本地磁盘中保存的资源副本。利用缓存能够减小向源服务器的访问,主要目的是减小网络带宽的流量和通讯时间。

缓存服务器是代理服务器的一种,当代理转发从服务器返回的响应时,会保存一份资源的副本。缓存服务器的优势在于经过缓存能够避免屡次从源服务器转发资源。所以客户端可就近从缓存服务器上获取资源,而源服务器也没必要屡次处理相同的请求。

缓存的有效期

每当源服务器上的资源更新时,若是仍是用不变的缓存,那就会变成返回更新前的旧资源。

即便存在缓存,也会由于客户端的要求、缓存的有效期等等一些因素,向源服务器确认资源的有效性。若是缓存的资源已过时,缓存服务器会向源服务器上获取新的资源。

客户端缓存

这里的客户端缓存指的是浏览器中的缓存。浏览器缓存若是未过时,就不用向源服务器请求相同的资源,直接获取缓存在本地磁盘中的资源。当资源过时时,会向源服务器确认资源的有效性。若是缓存的资源过时,就会再次向源服务器发起资源请求。

内容协商

内容协商机制是指客户端和服务器端就响应的资源内容进行互相协商,而后提供客户端最合适的资源。内容协商会以语言、字符集、编码方式等。

主要使用的请求头有:

  • Accept
  • Accept-Charset
  • Accept-Language
  • Content-Language

内容协商技术有下面三种类型。

  • 服务器驱动协商(Server-driven Negotiation)
    • 由服务器进行内容协商。
  • 客户端启动协商(Agent-driven Negotiation)
    • 由客户端进行内容协商。
  • 透明协商 服务器驱动和客户端驱动的结合体,由服务器和客户端进行内容协商的一种方法。

End-to-end头部和Hop-by-hop头部

HTTP 头字段定义成缓存代理和非缓存代理。分为两种类型。

  • 端到端头部End-to-end
    分在这个类别中的头部会转发给请求或响应对应的最终接收目标,并且必须保存在缓存生成的响应中,另外规定它必须被转发。
  • 逐跳头部Hop-by-hop
    分在这个类别中的头部只对单次转发有效,会因经过缓存或代理而不转发。在 HTTP 1.1 和以后的版本中,若是使用Hop-by-hop头,就要提供 Connection 头字段。

除了下面 8 个头字段外,其余全部字段都属于端到端头部。

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • Trailer
  • TE
  • Transfer-Encoding
  • Upgrade

HTTP通用头部字段

下面列出请求/响应头都会出现的字段,这些字段都含有重要的信息。

Cache-Control

Cache-Control表示资源的缓存操做,参数是可选的,若是存在多个参数的话,以,分隔开。

请求头

在请求头中使用Cache-Control字段时,它的值以下:

  • no-cache:不使用强缓存,强制向源服务器再次验证缓存的资源是否过时(走协商缓存)。
  • no-store:不使用任何缓存,每次都向源服务器获取最新的资源。
  • max-age:以秒为单位。表示缓存的资源没有超过指定的时间,客户端就从缓存中获取资源。
  • min-fresh:以秒为单位。要求代理服务器返回至少还没过指定时间的缓存资源。
  • max-stale:即便是过时的资源,也照样接收。
  • only-if-cached:告诉代理服务器,从缓存中获取资源(若是有)。
  • no-transform:不能对资源进行转换,能够防止缓存或代理压缩图片等相似操做。
响应头

在响应头中使用Cache-Control字段时,它的值以下:

  • public:资源可被浏览器和代理服务器进行缓存。
  • private:资源只能够被浏览器进行缓存。其余都不能够。
  • no-cache:能够缓存,但每次使用前要向源服务器验证缓存资源是否过时。
  • s-maxage:只提供给代理服务器,表示代理服务器中的资源过时时长,用s-maxage后,会忽略max-ageExpires字段。
  • max-age:以秒为单位。设置缓存时间,若是没超过该时间,不用向服务器请求资源。若是超过,就证实资源已过时。若是响应头出现Expires字段,在 HTTP 1.1 中会有限处理max-age,而 HTTP1.0 中则相反。
  • must-revalidate:能够缓存,但必须向源服务器再次验证。若是请求失败,则返回504状态码。该字段会忽略max-stale
  • proxy-revalidate:要求缓存服务器对缓存的响应有效性进行确认。
  • no-transform:不能对资源进行转换,能够防止缓存或代理压缩图片等相似操做。

Connection

Connection字段决定当前 TCP链接 完成后,是否关闭链接。有如下两种。

  • keep-Alive:持久化链接。
  • close: TCP 链接完成后,立马关闭链接。

Date

Date字段的值为GMT时间日期格式,表示 HTTP 报文建立的时间和日期。

Date: Tue, 13 Apr 2021 12:35:41 GMT
复制代码

Pragma

Pragma是用来向后兼容只支持 HTTP1.0 协议的缓存服务器。它的效果和Cache-Control同样。

Pragma: no-cache
复制代码

Upgrade

Upgrade用于查看 HTTP 协议或者其余协议是否可使用更高的版本进行通讯。

Upgrade: HTTP/2.0
Connection: Upgrade <!-- 表示删除了Upgrade后再转发 -->
复制代码

Via

Via用于跟踪客户端和服务器端之间的请求和响应报文的传输路径,还能够避免请求循环的发生。

<!-- 通过单个代理服务器 -->
Via: 1.0 gw.hackr.jp(Squid/3.1)

<!-- 通过多个代理服务器 -->
Via: 1.0 gw.hackr.jp(Squid/3.1), 1.1 al.example.com(Squid/2.7)
复制代码

通过代理服务器 A 时,Via头部附加了 “1.0 gw.hackr.jp(Squid/3.1)” 这样的字符串值。行头 1.0 指的是接收请求的服务器上应用的 HTTP 协议版本。若是通过多个代理服务器的话,这些信息会后面追加。

Warning

Warning字段告诉用户一些与缓存有关的警告。

请求头字段

Accept

Accept请求头用来告诉服务器,客户端能处理的内容类型。下面列出几种媒体类型。

  • 文本文件: text/htmltext/plaintext/cssapplication/xhtml+xmlapplication/xml等等。
  • 图片文件: image/jpegimage/gifimage/png;
  • 视频文件: video/mpegvideo/quicktime;
  • 二进制文件:application/octet-streamapplication/zip;

当值为*/*,表示客户端能够是任意内容类型。当值为image/*,用来表明任何其余图片类型。

若是想给显示的媒体类型增长优先级,经过用q=表示权重值,用分号(;)分隔开。权重值的范围是0~1,能够精确到小数点后 3 位,1是最大值。没有指定权重值时,默认权重是q=1.0

Accept: text/html, appliaction/json;q=0.9
复制代码

Accept-Charset

Accept-Charset请求头用来告诉服务器,客户端可处理的字符集类型。另外,能够一次性指定多种字符集。和Accept同样,经过q值来表示优先级。该头部应用于内容协商机制的服务器驱动协商。

Accept-Charset: iso-8859-1

Accept-Charset: iso-8859-1;q=0.5
复制代码

Accept-Encoding

Accept-Encoding请求头用来告诉服务器,客户端能理解的内容编码方式。能够一次性指定多种内容编码,有如下几种编码。

  • gzip:由文件压缩程序 gzip 生成的编码格式,使用 Lempel-Ziv 算法以及 32 位循环冗余验证。
  • compress:由 UNIX 文件压缩程序compress生成的编码方式,采用Lempel-Ziv-Welch算法。
  • deflate:组合使用 zlib 格式以及由deflate压缩算法生成的编码方式。
  • indentity:不执行压缩或不会变化的默认编码格式。
Accept-Encoding: gzip, deflate
复制代码

Accept同样,用q值来设置优先级。还有使用星号(*),表示指定任意的编码格式。

Accept-Language

Accept-Language请求头用来告诉服务器,客户端能够理解的天然语言集(指中文和英文集),以及天然语言集的优先级。和Accept同样的,可指定多个天然语言集。使用q值设置优先级。

Accept-Language: zh-CN,zh;q=0.9;q=0.8
复制代码

客户端在服务器有中文版的状况下,会请求返回中文版的响应,若是没有,则返回英文版。

Authorization

Authorization用来告诉服务器,用户代理的认证信息(证书值)。一般会在服务器返回401状态码响应后,把头部字段Authorization添加到请求中。

Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
复制代码

Expect

Expect用来告诉服务器,只有在知足这个条件的状况下才会处理请求。若是服务器不能知足客户端的要求,会返回417状态码。目前只规定了100-continue这个条件。

Expect: 100-continue
复制代码

From

From字段表示用户代理的用户的电子邮箱地址,目的是为了显示搜索引擎用户代理的负责人的电子邮箱联系方式。

From: info@hackr.jp
复制代码

Host

Host请求头指明了请求的资源所在的服务器主机名和端口号。若是服务器没设置主机名,会发送一个空值。

Host: www.tutu.com
复制代码

If-Match

像这种If-xxxx开头的请求头字段,都是条件请求。服务器接收到附带条件的请求后,只判断条件是真时才会执行请求。

If-Match字段用于和服务器资源的ETag值作对比时,ETag值和If-Match的值相等时才会处理该请求。不然返回412状态码。经过用星号(*)的方式,表示只要资源存在就处理请求,但服务器会忽略掉ETag的值。

If-Match: "123456"
复制代码

If-Modified-Since

If-Modified-Since用于肯定代理服务器或客户端的资源有效性。在指定的时间以后,请求的资源发生改变时,就处理请求。若是资源都没有改变,则返回304状态码。

If-Modified-Since: Tue, 13 Apr 2021 12:35:41 GMT
复制代码

If-None-Match

If-None-MatchIf-Match相反,只有服务器资源的ETag的值和If-None-Match的值不同时,才会处理该请求。在GETHEAD请求方法中加入该字段能够获取最新的资源。

If-Range

If-Range用于告诉服务器,若是If-Range字段的值和请求资源的ETag值或时间同样时,就会做为范围请求处理(Range字段规定请求多少字节的数据)。不然,忽略范围请求,返回所有资源。

If-Range: "123456"
Range: bytes=5001-10000
复制代码

If-Unmodified-Since

If-Unmodified-Since字段用来告诉服务器,只有当请求资源在指定的时间以后没有修改的状况下,才会处理请求。若是在指定的时间后发生了修改,则返回412状态码。

If-Unmodified-Since: Tue, 13 Apr 2021 12:35:41 GMT
复制代码

Proxy-Authorization

Proxy-Authorization字段包含了用户代理提供给代理服务器用于身份验证的凭证。

Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
复制代码

Range

Range请求头字段表示获取资源的哪一部分。服务器收到带有Range字段的请求后,会在处理请求以后返回206状态码。若是没法处理,则返回200状态码并把所有资源返回。

Range: bytes=5001-10000 <!-- bytes=5001-10000为资源的字节 -->
复制代码

Referer

Referer字段表示请求的URL是从哪一个 Web 页面发起的。服务器经过Referer字段来标识访问来源,进行统计分析、日志记录和缓存优化。

Referer: www.tutu.com <!-- 请求是由www.tutu.com发起的 -->
复制代码

TE

TE表示客户端可以处理响应的传输编码方式以及优先级。

TE: gzip, deflate;q=0.5
复制代码

User-Agent

User-Agent字段用于把请求的浏览器和用户代理名称等信息传给服务器。

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
复制代码

响应头字段

Accept-Ranges

Accept-Ranges表示服务器端能处理指定范围内的资源。有两个值:bytesnonenone表示不能处理指定范围内的请求。

Age

Age表示源服务器再多久前返回过资源。单位为秒。

Age: 3600
复制代码

ETag

ETag表示资源的特定标识符,服务器会给每份资源都分配对应的ETag值。当资源发生变化时,ETag值也会改变。例如,访问同一个 URL 的网站同时具有有中英文版,当切换中文时,会返回中文的资源(ETag: user-chi),而切换到英文时,返回的是英文的资源(ETag: user-us)。

强弱ETag
  • 强ETag: 无论资源发生了什么变化都会改变其值。
ETag: "user-123456"
复制代码
  • 弱ETag: 用于资源是否相同,只有资源发生了根本改变,产生差别时才会改变ETag值。字段值最开头会添加W/的字符
ETag: W/"user-123456"
复制代码

Location

Location字段表示须要将页面重定向到某个地址,通常都是响应码为3xx的响应才有用。

Location: www.baidu.com <!-- 重定向到www.baidu.com -->
复制代码

Proxy-Authenticate

Proxy-Authenticate字段表示获取代理服务器的资源要经过身份验证的方式。

Retry-After

Retry-After字段表示客户端应该在多久以后再次请求。配合5033xx状态码响应一块儿使用。

Retry-After: 120
复制代码

Server

Server字段表示处理请求的服务器所用到的软件相关信息。

Server: Apache/2.2.17
复制代码

Vary

Vary字段能够对缓存进行控制。从代理服务器收到源服务器返回含有Vary指定项的响应后,若是要进行缓存,那么会对请求中含有Vary指定头部字段的请求返回缓存。即便对相同资源发起请求,若是Vary指定的头部字段不相同,就必须从源服务器从新获取资源。

Vary: Accept-Language
复制代码

实体头字段

Allow

Allow用于告诉客户端,资源所支持的 HTTP 方法,若是服务器收到不支持的 HTTP 方法时,会返回405状态码做为响应。

Allow: GET, DELETE 
复制代码

Content-Encoding

Content-Encoding字段表示服务器对实体的主体部分用的内容编码方式。内容编码在Accept-Encoding中已经介绍过,一共有4种。

Content-Encoding: gzip
复制代码

Content-Language

Content-Language字段表示实体主体使用的天然语言。

Content-Language: zh-CN
复制代码

Content-Length

Content-Length表示实体主体部分的大小(以字节为单位)。

Content-Length: 1500
复制代码

Content-Location

Content-Location字段表示要返回数据的地址。

Content-Location: https://www.tutu.com/index.html
复制代码

Content-Range

Content-Range字段表示的是一个数据片断在整个文件中的位置。

Content-Range: bytes 5001-10000/10000
复制代码

Content-type

Content-type字段表示实体主体中对象的媒体类型。

Content-type: text/html; charset=UTF-8
复制代码

Expires

Expires字段会把资源失效的日期告诉客户端。在这个日期后,资源就会过时。也就是说,在指定的日期内能够从浏览器缓存中获取资源。若是超过了这个日期,就必须向服务器发起资源请求。若是头部存在Cache-Control: max-age时,会优先处理max-age指令。

Expires: Tue, 13 Apr 2021 12:35:41 GMT
复制代码

Last-Modified

Last-Modified字段表示资源最后修改的时间。

Last-Modified: Tue, 13 Apr 2021 12:35:41 GMT
复制代码

HTTP 缓存

HTTP 缓存可分为强缓存协商缓存,主要用于加快资源的获取速度,提升用户体验,减小网络链接,缓解服务器压力。

强缓存

对强缓存来讲,浏览器会判断请求的资源是否在有效期内。若是是在有效期内,就直接从缓存中读取资源,不用向服务器发送资源请求。强缓存经过ExpiresCache-ControlPragma这三个头部字段设置。

Cache-Control

Cache-Control头部字段在上面也详细介绍过在各端所具有的属性值。下面来列出最多见的几个值。

  • public: 该资源能够被浏览器和代理服务器进行缓存。
  • private: 该资源只能够被浏览器缓存,其余都不能够。
  • no-cache: 不使用强缓存,强制向源服务器再次验证缓存的有效性。这个值表示走协商缓存。
  • no-store: 不使用任何缓存,每次都向源服务器获取最新资源。
  • max-age: 若是缓存的资源没有超过规定的时间,客户端就从缓存中获取资源。以秒为单位。
  • s-maxage: 只适用于代理服务器,表示代理服务器中的资源过时时长,用了s-maxage后,会忽略max-ageExpires字段。
Expires

Expires字段的值是一个GMT格式的时间日期,将资源失效的日期告诉客户端,客户端收到带有该字段的响应体后进行缓存。后续客户端发起相同的资源请求,会用Expires的值和本地时间作对比,若是该请求的本地时间小于Expires的值,就直接用缓存中的资源,不用向服务器发起请求。

Expires的值会产生一个问题。若是修改了本地时间,就会致使客户端和服务器端的时间不一致,那么对于缓存过时的判断就没法和预期同样了。

Expires在三者中优先级最低。

Pragma

Pragma能够看上面的介绍,这里不过多讲解。

强缓存在 Chrome 中会返回200状态码而且有两种状况。

  • memory cache: 只要页面不关闭,就会从浏览器内存中获取资源。
  • disk cache: 从磁盘中读取缓存资源。

强缓存.jpg

用了强缓存后,若是服务器端的资源更新了,客户端是不知道的,并且在过时以前都会用缓存中的资源。能够经过Ctrl + F5强制刷新。

协商缓存

协商缓存是在用本地缓存以前,会向服务器发起一次GET请求,验证浏览器保存在本地的资源是否过时。

last-modified和if-modified-sine

通常状况下是用请求资源的最近一次修改时间戳来判断。来举个例子:假设客户端向服务器端请求一个文件,为了让资源被再次请求时能经过协商缓存机制使用本地缓存。首次返回该资源的响应头中会包含一个last-modified的字段,字段的值表示资源最后修改的时间。当刷新页面时,该资源使用的是协商缓存,浏览器没法确认本地缓存是否过时,而后向服务器发起一次GET请求,进行缓存有效性的协商,本次请求的请求头中包含一个if-modified-since字段,字段的值是上次响应头中的last-modified字段的值。

last-modified的不足之处

last-modified存在两个缺陷:

  1. 它只是根据资源最后的修改时间进行判断,虽然请求的文件资源进行了编辑,但内容并无改变,时间也会更新。这就致使了协商缓存时关于有效性的判断验证失效,就要从新进行资源的请求。
  2. 因为文件资源修改的时间单位是秒,若是文件修改很频繁。好比,几百毫秒内改一次,就没法识别出该文件资源的更新。
ETag和if-none-match

为了弥补经过时间判断的不足,HTTP 1.1 加入了ETag(实体标签)的头信息。

ETag表示资源的特定标识符,相似文件指纹。做用上面也有提到,这里不过多讲解。

当响应头同时存在last-modifiedETag这两个字段时,会以ETag为准。再次对该资源发起请求时,会将以前的响应头中ETag的值看成此次请求中if-none-match字段的值,发送给服务器进行缓存有效性验证。若是验证缓存有效,就返回304状态码响应重定向到本地缓存。

ETag的不足之处

ETag的出现并非last-modified的代替品,而是一种补充方案,它仍是存在弊端的。

  • 若是资源比较大,数量多并且修改频繁的话,那么生成ETag的过程会影响到服务器的性能。
  • 上面也讲了ETag还分强ETag和弱ETag
    • ETag值是根据资源内容进行生成,保证每一个字节都相同。
    • ETag值是根据资源的部分属性值来生成,生成速度快可是没法保证每一个字节都相同。

若是浏览器走的是协商缓存,而且资源没发生改变,服务器端会返回304状态响应码告诉浏览器获取本地缓存的资源便可。

1617632172962.jpg

HTTP 的缺点

HTTP协议主要的不足之处有如下几点。

  • 通讯使用明文,内容会被窃听
  • 不验证通讯方的身份,可能遭遇假装
  • 没法证实报文的完整性,可能已遭到篡改

通讯使用明文,内容会被窃听

HTTP 协议自己没有加密功能,因此没法作到对通讯请求和响应内容进行加密。

TCP/IP 是会被窃听的网络

因为 TCP/IP 协议的工做机制,通讯内容在全部通讯线路上都有可能遭到窥视。无论是哪一个角落的服务器在跟客户端进行通讯,通讯的线路上的一些设备都不多是我的物品。因此不排除在某个环节上遭到恶意窥视的行为。即便进行加密处理,也会被窥视到通讯的内容。窃听相同端上的通讯并非难事,只要收集在网络上流动的数据包就行。能够经过抓包和嗅探器工具来收集数据包。

解决方案: 加密处理防止窃听

最多见的两种加密方式是通讯加密和内容加密

通讯加密

HTTP 协议中自己没有加密机制,但能够经过 SSL(Secure Socket Layer 安全套阶层)TLS(Transport Layer Security 安全传输层协议) 的组合使用,加密HTTP的通讯内容。用 SSL 创建安全通讯线路后,就能够在这条线路上进行 HTTP 通讯。和 SSL 组合使用的 HTTP 叫作 HTTPS (HTTP Secure 超文本传输安全协议) 或 HTTP over SSL。

内容加密

因为 HTTP 协议中没有加密机制,那么能够对传输的内容自己进行加密。也就是把 HTTP 报文中包含的内容进行加密处理。在这种状况下,客户端须要对 HTTP 报文主体(body)进行加密处理后再发送请求。要作到内容的加密,前提是客户端和服务器端同时具备加密和解密的机制。主要应用在 Web 服务器中。该方式不一样于 SSL 和 TLS 把整个通讯线路加密处理,因此内容仍是会有被篡改的可能。

不验证通讯放的身份可能遭遇假装

HTTP 协议的请求和响应都不会对通讯方进行确认。

任何人均可以发起请求

在 HTTP 协议通讯时,因为不存在肯定通讯方的处理步骤,任何人均可以发起请求。服务器只要收到请求,无论是谁都会返回一个响应(仅限发送端的 IP 地址和端口号没被 Web 服务器设置限制访问的前提下)。也就是来者不拒。

  • 有多是假装的服务器。
  • 有多是假装的客户端。
  • 没法肯定正在通讯的对方是否具有访问权限。由于某些 Web 服务器上保存有重要的信息,只想发给特定用户通讯的权限。
  • 没法判断请求是从哪来、出自谁手。
  • 即便是无心义的请求也照样接收。没法阻止大量请求下的 Dos 攻击(Denial of Service,拒绝服务器攻击)。

解决方案:查明对方的证书

虽然使用 HTTP 协议没法肯定通讯方,但使用 SSL 能够。SSL 除了加密处理外,还用了一种证书的手段,用于确认通讯方。证书是由值得信任的第三方机构颁发,用来证实服务器和客户端是真实存在的。

经过证书,以证实通讯方就是意料中的服务器,对我的来讲,减小了我的信息泄露的危险。另外,客户端持有证书便可完成我的身份的确认,也可用于对 Web 网站的认证环节。

没法证实报文完整性,可能已篡改

收到的内容不完整

没有任何办法确认,发出去的请求或响应和接收到的请求或响应是先后相同的。有可能在中途被篡改为其余的内容,即便内容是真的被改了,接收方也不会知道。

解决方案:MD5 和 SHA-1

可使用 MD5 和 SHA-1 等散列值校验方法,以及用来确认文件的数字签名方法(PGP签名)对内容进行加密。可是用这些方法也没法保证正确,由于 MD5 和 PGP 自己被修改的话,用户也不会知道。

HTTPS

HTTP加上加密处理和认证以及完整性保护机制就是HTTPS

HTTPS 是身披 SSL 外壳的 HTTP

HTTPS 不是应用层的一种新协议。只是 HTTP 通讯接口部分用 SSL 和 TLS 协议代替而已。以前是 HTTP 和 TCP 进行通讯,用了 SSL 以后,就变成了 HTTP 先和 SSL 通讯,以后 SSL 和 TCP 通讯。

HTTPS.png

使用 SSL 以后,HTTP 就有了 HTTPS 的加密、证书和完整保护性这些功能。

加密方式

SSL 用的是公开密钥加密的处理方式。加密方法中的加密算法是公开的,密钥则是保密的。经过这种方式能够保持加密方法的安全性。

加密和解密都会用到密钥。没有密钥就没办法对密码解密,任何人只要有密钥就能够进行解密,若是密钥被攻击者得到,那么加密也就没有意义了。

对称加密

加密和解密同用一个密钥的方式叫作共享密钥加密,也称为对称密钥加密。也就是说,客户端和服务器端共用一个密钥对消息进行加密。客户端在发送请求时,会用密钥对消息加密。服务器收到后,再用密钥对消息进行解密。

缺点

对称加密虽然保证了消息保密性,但客户端和服务器端用的都是同一个密钥,若是说在传输的过程当中出现了中间人或攻击者。密钥就有可能落到攻击者手中,这样就对消息加密就没有什么意义了。

非对称加密

非对称加密解决了对称加密的缺点。非对称加密用的是一对非对称的密钥。一把叫作私有密钥,另外一把叫作公开密钥。私有密钥只能是本身所拥有,而公开密钥则是任何人均可以拿到。

当客户端发送消息前,使用公共密钥进行加密,而服务器收到消息后,使用私有密钥进行解密。

缺点

非对称加密须要在发送端在发送消息时,用公钥加密。但公钥是任何人均可以拿到,中间人也能够。中间人虽然不知道接收方的私钥是什么,但能够截获发送端的公钥,本身另外生成一把公钥或者篡改公钥,把公钥发给接收端。并且非对称加密处理起来比对称加密的方式更加复杂,这样就致使了效率变低。

混合加密机制

HTTPS 用的就是对称加密和非对称加密二者的混合加密。使用对称加密的好处是解密效率快,使用非对称加密的好处是在传输消息的过程当中不会被破解。即便截获了数据,没有对应的私钥,也没法对消息进行破解。

摘要算法

数字摘要是采用 Hash 函数将须要加密的明文 “摘要” 成一串固定长度(128位)的密文,这串密文又称为数字指纹,它有固定长度,并且不一样的明文摘要成密文,其结果老是不一样,而一样的明文摘要必须一致。数字摘要是 HTTPS 能确保数据完整性和防篡改的根本缘由。

数字签名

数字签名是非对称加密和数字摘要两项技术的应用,它将摘要信息用发送者的私钥加密,和原文一块儿发给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,而后用 Hash 函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。若是同样,那就说明收到的信息是完整的。不然说明信息被修改过,所以数字签名可以验证信息的完整性。

签名是加密的校验码

数字签名是附加在报文上的特殊加密校验码。使用数字签名有如下两点好处。

  • 签名能肯定消息是由发送方签名并发过来的,由于别人假冒不了发送方的签名。
  • 签名能肯定消息的完整性,证实数据没有被篡改过。

数字签名的过程以下: 明文 -> hash运算 -> 摘要 -> 私钥加密 -> 数字签名

数字证书

数字证书(CA)就像咱们的身份证同样,信息都是惟一性的。它是属于可信任的一些第三方机构全部。证书包含了如下的信息。

  • 证书的发布机构 CA
  • 证书的有效期
  • 公钥
  • 证书全部者
  • 签名

数字证书还包括对象的公钥,对象和所用签名算法的描述信息。全部人均可以建立一个数字证书,但并非全部人都能得到签发权,从而为证书信息担保,并用它私有密钥签发证书。

HTTPS 的工做流程

  1. 首先是客户端向服务器端发起一个 HTTPS 请求。
  2. 服务器端返回公钥证书给客户端。
  3. 客户端收到公钥证书后,用证书的公钥验证数字签名,以确认服务器的公钥的真实性。
  4. 客户端用随机数生成器生成临时的会话密钥,而后用服务器的公钥对该会话密钥进行加密,发送给服务器端。
  5. 服务器收到后,用本身的密钥对会话密钥解密。
  6. 以后客户端和服务器端就开始了 HTTPS 通讯。

SSL 和 TSL

HTTPS 用的是 SSL(Secure Socket Layer 安全套阶层) 和 TLS(Transport Layer Security 安全传输层协议)这两个协议。SSL 最开始是网景先倡导,后来网景凉了,就转移给了 IETF 的手里。IETF 以 SSL 3.0 为准,以后又定制了 TLS1.0、TLS1.1和 TLS1.2。TLS 是以 SSL 为原型开发的协议。有时候统一称该协议为 SSL。

为何不一直用 HTTPS

凡事都具备两面性,不是说 HTTPS 安全就没有问题了。其实它仍是存在一些问题的。在使用 SSL 时,它的处理速度会变慢。其缘由有两种,一是通讯慢,二是每次都进行加密通讯,就致使消耗大量的 CPU 和内存资源,致使处理速度变慢。

  • 除了和 TCP 链接、发送请求和响应以外,还要和 SSL 进行通讯。
  • 另外 SSL 要进行加密处理,在服务器和客户端都要进行加密和解密的运算处理。
  • 要用 HTTPS 通讯,购买证书是必不可少的。

固然能够用 SSL 加速(专用服务器)硬件来改善效率的问题。能够提升 SSL 的计算速度,分担负载。但只有在 SSL 处理时才发挥 SSL 加速器的效果。像一些非敏感的信息就用 HTTP 进行通讯,对于敏感信息采用 HTTPS 通讯,以节约资源。

HTTP 和 HTTPS 的区别

  1. HTTP 是以明文的方式进行传输,HTTPS 则是具备安全性的 SSL 加密传输协议。
  2. HTTP 和 HTTPS 用的是两种不一样的方式进行链接,端口号也不同。前者是 80,后者是 443
  3. 想要用 HTTPS 就得购买证书(CA),而免费的整数通常都不多,因此须要支付必定的费用。
  4. HTTPS 对搜索引擎更友好,有利于 SEO ,优先索引 HTTPS 的网页。
  5. HTTP 的链接简单,而且是无状态的。HTTPS 是由 SSL + HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 要安全。

解决 HTTP 1.x 瓶颈的 SPDY

HTTP 1.x的缺点

HTTP 1.x主要有如下几个缺点:

  1. HTTP 1.0 只容许在一个 TCP 链接上发送一个请求,HTTP 1.1中默认容许多个 TCP 链接。可是同一个 TCP 链接中,全部的数据通讯都是按次序进行的,服务器通常是处理完一个响应以后,再继续处理下一个。这就形成了队首阻塞问题。
  2. 请求只能从客户端开始,客户端不能够接收除了响应以外的指令。
  3. 请求/响应头部不进行压缩就发送。头部信息越多延迟就越大。
  4. 发送冗长的头部,每次互相发送相同的头部致使资源浪费。
  5. 可随意选择数据压缩格式,非强制压缩发送。

SPDY

SPDY 是由谷歌开发的基于 TCP 协议的应用层协议。目标是为了优化 HTTP 协议的性能,经过压缩、多路复用和优先级技术,缩短网页的加载时间并提升安全性。SPDY 协议的核心思想是尽可能减小 TCP 的链接数。SPDY 并非一种代替 HTTP 的协议,而是对 HTTP 协议的加强。

SPDY 没有改写 HTTP 协议,而是在 TCP/IP的应用层和传输层之间经过新加会话层的形式运做。同时,考虑到安全问题,SPDY 规定通讯中使用 SSL。

SPDY.jpg

SPDY 以会话层的形式加入,控制对数据的流动,但仍是采用 HTTP 创建通讯。所以,能够照常使用 HTTP 的请求方法、Cookie 以及 HTTP 报文等等。

HTTP 2.0

HTTP 2.0 能够说是 SPDY 的升级版(实际上是基于 SPDY 设计的),但HTTP 2.0和 SPDY 仍是存在一些不一样的。主要有如下两点:

  1. HTTP 2.0 支持明文传输,而 SPDY 强制使用 HTTP。
  2. HTTP 2.0 消息头的压缩算法用的是 HPACK,而 SPDY 用的是 DEFLATE。

下面就简单的介绍一下 HTTP 2.0 新增的功能。因为HTTP 2.0 设计到的东西太多了,以后我会一篇文章单独讲讲 HTTP 2.0。

  • 二进制分帧层:HTTP 2.0 性能加强的核心就是新增的二进制分帧层,HTTP 1.x是以换行符做为纯文本的分隔符,而 HTTP 2.0 把全部传输的信息分割成更小的消息,并对它们采用二进制的格式编码。

  • 多向请求和响应:HTTP 2.0 中心的二进制分帧层,将 HTTP 消息分解成独立的帧,交错发送。而后在另外一个端根据流标识符和头部把它们从新组装。解决了 HTTP 1.x的队首阻塞问题。

  • 请求优先级:把 HTTP 消息分解成多个独立的帧后,就能够经过优化这些帧的交错和传输顺序进一步性能优化。

  • 服务器推送:服务器能够对一个客户端请求发送多个响应。服务器还能够向客户端推送资源并且无需客户端明确的请求。

  • 头部压缩:在 HTTP 2.0 中,使用了 HPACK(HTTP2头部压缩算法)压缩格式对传输的头部进行编码,减小了头部的大小。并在两端维护了索引表,用于记录出现过的头部,以后在传输过程当中就能够传输已经记录过的头部健名,对端收到数据后就能够经过键名找到对应的值。

若是想要了解更多 HTTP2.0 的知识能够看看《Web性能权威指南》这本书,里面讲得挺详细的。

补充

OSI模型

网络架构模型除了TCP/IP模型以外,还有OSI模型OSI模型其实是多了三层。

OSI模型.png

也就是上面所说的多加了 SSL 和 SPDY 这两个协议(都处于应用层)。

而数据链路层细分的话有两层:

  • 数据链路层: 在不可靠的物理链路上,提供可靠的数据传输服务。包括组帧、物理编址、流量控制、差错控制、接入控制等等。
  • 物理层: 主要功能就是链接网络设备。

Cookie

前面也说到,HTTP 是无状态的协议,它不会对以前发送过的请求和响应的状态进行管理。假设,客户端的用户发送一个请求,服务器端收到请求后想知道这个请求是哪一个家伙发过来的,那么就要有一个状态进行管理。而Cookie正是解决这类问题而出现。

从服务器端返回的响应头信息中有一个Set-Cookie的字段信息,告诉客户端保存Cookie。在下次客户端向服务器端发送请求时,客户端会自动在请求头信息中加入Cookie的值发送出去。

服务器收到客户端发送过来的Cookie以后,会检查究竟是从哪一个客户端发送过的请求,而后对比服务器上的记录,最后获得了以前的状态信息。

Set-Cookie

Set-Cookie是属于响应头中的一个字段,它包含如下的值。

  • NAME=VALUE: Cookie的名称和值。
  • expires=DATE: Cookie的有效期。
  • path=PATH: 把服务器上的文件目录做为Cookie的使用对象,若是没有设置,默认是文档所在的文件目录。
  • domain=域名: 做为Cookie适用对象的域名,若是没有设置,默认是建立Cookie的服务器的域名。
  • Secure: 只有在 HTTPS 时才会发送Cookie
  • HttpOnly: JavaScript 不能访问Cookie。主要是为了防止跨站脚本攻击时Cookie的信息窃取。

请求头中的Cookie字段

Cookie是请求头中的一个字段,它包含服务器经过Set-Cookie头部设置并存到客户端的值。若是接收多个Cookie时,能够以多个Cookie形式发送回去。

cookie.jpg

最后

以上是我一个多月在学 HTTP 相关书籍作的一些笔记。哪里有不对的地方,请各位大佬多多指点!固然文章对你有所帮助,欢迎点赞加关注哦!

参考

相关文章
相关标签/搜索