你们好,我是图图。也有一个多月没有写文章了。因为各类缘由,被迫提桶,真是艰难。通过几轮的面试以后,被面试官虐得惨惨的,其中许多缘由是没有仔细的学过 HTTP 的知识,我对这块的知识相对来讲比较薄弱,因此决定把数据结构和算法得先放一放了。因此把 HTTP 的知识学一遍,而后再补一下JS的基础。css
下面废话很少说,咱们开始吧!html
HTTP是一种超文本传输协议,用于完成客户端和服务器端等等一系列的运做流程。而协议指的是规则的约定。能够说,Web 是创建在 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 月实现了标准化。
在理解 HTTP 以前,咱们先简单的来了解一下 TCP/IP 协议族。通常使用的网络都是在 TCP/IP 协议的基础上运做的,而 HTTP 属于它内部的一个子集。
在计算机和网络设备进行互相通讯时,双方都必须基于相同的方法。好比,如何探测到通讯目标,是哪边先发起通讯、用什么语言进行通讯、怎样结束通讯等等一些规则都是先要肯定好的。不一样的硬件、操做系统之间的通讯,全部的这一切都须要一种规则。而这种规则称为协议
。
协议中包括:从电缆的规格到 IP 地址的选定方法、寻找异地用户的方法、双方创建通讯的顺序,以及 Web 页面显示要处理的步骤,等等。将这些相关联的协议集合起来总称为 TCP/IP。
TCP/IP 重要的点就是分层。有如下4
层:应用层、传输层、网络层和数据链路层。
下面来介绍各层的做用。
应用层:应用层决定了向用户提供应用服务时通讯的活动。好比,FTP(文件传输协议)和 DNS(域名解析系统)。HTTP 协议也在该层。
传输层:传输层对上层应用层,提供处于网络链接中的两台计算机之间的数据传送。该层有两个不一样的协议:TCP 传输控制协议和 UDP 用户数据协议。
网络层:网络层用来处理在网络上的数据包。数据包是网络传输的最小数据单位。网络层的做用就是在多条路线中选出一条传输路线进行数据传输。
链路层:用来处理链接网络的硬件部分。包括什么操做系统、硬件的设备、什么路由器啊之类的等等,都属于该层。
TCP/IP 层次化的好处是:若是互联网由一个协议统一规划,某个地方须要改变设计时,就必须将全部部分总体替换掉。而分层以后只须要把变更的层替换掉。把各层之间的接口部分规划好以后,每层内部的设计就能够自由改动。好比,处于应用层上的应用能够只考虑分配给本身的任务,不用去考虑其余的问题。
TCP/IP 协议进行通讯时,会经过分层顺序和对方进行通讯。客户端从应用层往下走,服务器端则从链路层往上走。看下面的图。
在HTTP客户端向服务器端发送报文以前,须要用到 IP、TCP、DNS 这三个和 HTTP 密不可分的协议。
IP(Internet Protocol
)网络协议处于网络层。IP协议的做用是把各类数据包传送给对方。但要保证正确的传送给对方,其中两个重要的条件是 IP 地址和 MAC 地址。能够把它想象成你家的地址,或者说你的电话号码。
IP 地址指的是节点被分配到的地址,MAC 地址指的是网卡所属的固定地址。IP 地址能够跟 MAC 地址进行配对。IP 地址是可变的,MAC 地址是不可变的。
IP 和 IP地址别搞混了,IP是一种协议。而IP地址是则是每台计算机的标识
IP 间的通讯依赖 MAC 地址。在网络上通讯的双方不多会在同一个局域网,通常都是通过多台计算机或者网络设备中专才能链接到对方。而在中转的过程当中,会利用下一站中转设备的 MAC 地址进行搜索下一个中转目标。而这时,会用到ARP协议。ARP协议是一种用来解析地址的协议,经过通讯方的 IP 地址就能反查出对应的 MAC 地址。
在到达通讯目标前的中转过程当中,计算机和路由器只能获取粗略的传输路线,这种机制叫作路由选择。
就跟你在淘宝上买东西是同样的道理。好比,你在淘宝网买了件衣服,快递公司会根据你的地址进行送货,在送货这个过程当中,并非直接送到你手里。而是通过各类什么杭州中转站而后又到深圳中转站,以后才送到你手里。
TCP 协议处于传输层,主要的做用是提供可靠的字节流服务。字节流服务指的是,为了方便传输,将大块的数据分割成以报文段为单位的数据包进行管理。而可靠性的传输服务指的是,可以把数据准确可靠的传给对方。
为了准确的将数据传送给对方,三次握手就出现了。下图展现这个过程。
DNS 服务和 HTTP协议同样,处于应用层。它主要的做用是,将域名解析成 IP 地址。DNS 协议能够经过域名查找 IP 地址,也能够经过 IP 地址反查域名的服务。
下面展现每一个协议和HTTP协议的关系。
http://www.tutu.com
。Uniform Resource Identifier
,它的做用是区分互联网中的不一样资源。好比,HTML 文档、图像、视频片断、程序等等。而 URL 是 URI 的一个子集。下图展现了 URI 的格式。
http:
或https:
表示协议名称。不区分字母大小写,最后加上//
。user:pass@
表示获取服务器资源的用户和密码。但不推荐使用,由于不安全。www.tutu.com
;192.168.0.1
地址名;[0:0:0:0:0:0:1]
这种方括号括起来的 IPv6 地址;:8080
表示端口号。/html/index.html
表示服务器文件路径,资源的访问位置。?userId=1
表示文件路径中的参数。?
后面以key=value
的形式。若是后面还须要加参数,用&
拼接。#cn1
表示文件中的某个位置。就是平时的网页锚点定位。HTTP 是一种无状态的协议,对发送过的请求/响应都不作持久化处理。
HTTP 1.1 中的全部链接都是默认开启的(keep-alive
)。经过请求/响应头部的Connection
字段能够查看是否开启持久化链接(后面会介绍该字段的值),而在 HTTP1.0中是默认关闭的(close
)。
它的特色是,无论是客户端仍是服务器端,只要其中的一端没有提出断开链接,那么就会保持 TCP 链接。好处是,减小 TCP 链接的重复创建和断开链接形成的额外开销,减轻服务器压力。这样使得 HTTP 请求和响应速度更快结束,也提升页面的显示速度。
管线化是不用等待响应就能够发送下一个请求,也就是并行处理。不用一个接一个的等待响应,管线化比持久化链接还要更快。
HTTP 一共有两种报文:请求报文、响应报文。报文又分为报文头部和报文主体,报文主体是可选的。报文包含了如下三个部分。
start line
)有如下两种类型。
header
):一些头部信息,以key: value
的形式。body
):被发送的数据。这张图是以请求报文为例。
1XX
表示接收的请求正在处理。
200 OK
:表示客户端发送的请求在服务器端被正常处理了。204 No Content
:表示请求被处理成功,但没有资源可返回。206 Partial Content
:表示客户端只获取文件的一部份内容,而服务器成功执行了这部分的GET
请求。响应报文中含Content-Range
指定部分的实体内容。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的,但实际使用的时候你们都会这么作。
400 Bad Request
:表示请求报文中存在语法错误。401 Unauthorized
:表示发送的请求要经过 HTTP 认证的认证消息。若是以前请求过一次,就表示用户认证失败。403 Forbidden
:表示对请求资源的访问被服务器拒绝。404 Not Found
:表示服务器上没法找到请求的资源。500 Internal Serve Error
:表示服务器端在执行请求时发生错误。503 Service Unavailable
:表示服务器暂处于超负荷或者正在进行停机维护。HTTP进行通讯时,除了客户端和服务器端这两个以外,还有一些用于通讯数据转发的应用程序。例如代理、网关、隧道和缓存。
代理是一种具备转发功能的应用程序,它存在于客户端和服务器端之间,至关于一个中间人。它将客户端发送过来的请求并转发给服务器端。固然,它也会将服务器端返回的响应转发给客户端。
每次经过代理服务器转发请求或响应时,头部都会出现Via
这个字段。
网关是一种特殊的服务器,做为其余服务器的中间实体使用。用于将 HTTP 请求转化成其余协议通讯。网关接收请求时就好像本身的资源的源服务器同样对请求作处理。
隧道是可按要求创建一条和其余服务器的通讯线路,到时候使用 SSL 加密进行通讯。隧道的目的是保证客户端和服务器进行安全的通讯。
缓存是指代理服务器或客户端本地磁盘中保存的资源副本。利用缓存能够减小向源服务器的访问,主要目的是减小网络带宽的流量和通讯时间。
缓存服务器是代理服务器的一种,当代理转发从服务器返回的响应时,会保存一份资源的副本。缓存服务器的优势在于经过缓存能够避免屡次从源服务器转发资源。所以客户端可就近从缓存服务器上获取资源,而源服务器也没必要屡次处理相同的请求。
每当源服务器上的资源更新时,若是仍是用不变的缓存,那就会变成返回更新前的旧资源。
即便存在缓存,也会由于客户端的要求、缓存的有效期等等一些因素,向源服务器确认资源的有效性。若是缓存的资源已过时,缓存服务器会向源服务器上获取新的资源。
这里的客户端缓存指的是浏览器中的缓存。浏览器缓存若是未过时,就不用向源服务器请求相同的资源,直接获取缓存在本地磁盘中的资源。当资源过时时,会向源服务器确认资源的有效性。若是缓存的资源过时,就会再次向源服务器发起资源请求。
内容协商机制是指客户端和服务器端就响应的资源内容进行互相协商,而后提供客户端最合适的资源。内容协商会以语言、字符集、编码方式等。
主要使用的请求头有:
内容协商技术有下面三种类型。
HTTP 头字段定义成缓存代理和非缓存代理。分为两种类型。
End-to-end
Hop-by-hop
Hop-by-hop
头,就要提供 Connection
头字段。除了下面 8 个头字段外,其余全部字段都属于端到端头部。
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
Trailer
TE
Transfer-Encoding
Upgrade
下面列出请求/响应头都会出现的字段,这些字段都含有重要的信息。
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-age
和Expires
字段。max-age
:以秒为单位。设置缓存时间,若是没超过该时间,不用向服务器请求资源。若是超过,就证实资源已过时。若是响应头出现Expires
字段,在 HTTP 1.1 中会有限处理max-age
,而 HTTP1.0 中则相反。must-revalidate
:能够缓存,但必须向源服务器再次验证。若是请求失败,则返回504
状态码。该字段会忽略max-stale
。proxy-revalidate
:要求缓存服务器对缓存的响应有效性进行确认。no-transform
:不能对资源进行转换,能够防止缓存或代理压缩图片等相似操做。Connection
字段决定当前 TCP链接 完成后,是否关闭链接。有如下两种。
keep-Alive
:持久化链接。close
: TCP 链接完成后,立马关闭链接。Date
字段的值为GMT时间日期格式,表示 HTTP 报文建立的时间和日期。
Date: Tue, 13 Apr 2021 12:35:41 GMT
复制代码
Pragma
是用来向后兼容只支持 HTTP1.0 协议的缓存服务器。它的效果和Cache-Control
同样。
Pragma: no-cache
复制代码
Upgrade
用于查看 HTTP 协议或者其余协议是否可使用更高的版本进行通讯。
Upgrade: HTTP/2.0
Connection: Upgrade <!-- 表示删除了Upgrade后再转发 -->
复制代码
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
字段告诉用户一些与缓存有关的警告。
Accept
请求头用来告诉服务器,客户端能处理的内容类型。下面列出几种媒体类型。
text/html
、text/plain
、text/css
、application/xhtml+xml
、application/xml
等等。image/jpeg
、image/gif
、image/png
;video/mpeg
、video/quicktime
;application/octet-stream
、application/zip
;当值为*/*
,表示客户端能够是任意内容类型。当值为image/*
,用来表明任何其余图片类型。
若是想给显示的媒体类型增长优先级,经过用q=
表示权重值,用分号(;
)分隔开。权重值的范围是0~1
,能够精确到小数点后 3 位,1
是最大值。没有指定权重值时,默认权重是q=1.0
。
Accept: text/html, appliaction/json;q=0.9
复制代码
Accept-Charset
请求头用来告诉服务器,客户端可处理的字符集类型。另外,能够一次性指定多种字符集。和Accept
同样,经过q
值来表示优先级。该头部应用于内容协商机制的服务器驱动协商。
Accept-Charset: iso-8859-1
Accept-Charset: iso-8859-1;q=0.5
复制代码
Accept-Encoding
请求头用来告诉服务器,客户端能理解的内容编码方式。能够一次性指定多种内容编码,有如下几种编码。
gzip
生成的编码格式,使用 Lempel-Ziv
算法以及 32 位循环冗余验证。compress
生成的编码方式,采用Lempel-Ziv-Welch
算法。zlib
格式以及由deflate
压缩算法生成的编码方式。Accept-Encoding: gzip, deflate
复制代码
和Accept
同样,用q
值来设置优先级。还有使用星号(*
),表示指定任意的编码格式。
Accept-Language
请求头用来告诉服务器,客户端能够理解的天然语言集(指中文和英文集),以及天然语言集的优先级。和Accept
同样的,可指定多个天然语言集。使用q
值设置优先级。
Accept-Language: zh-CN,zh;q=0.9;q=0.8
复制代码
客户端在服务器有中文版的状况下,会请求返回中文版的响应,若是没有,则返回英文版。
Authorization
用来告诉服务器,用户代理的认证信息(证书值)。一般会在服务器返回401
状态码响应后,把头部字段Authorization
添加到请求中。
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
复制代码
Expect
用来告诉服务器,只有在知足这个条件的状况下才会处理请求。若是服务器不能知足客户端的要求,会返回417
状态码。目前只规定了100-continue
这个条件。
Expect: 100-continue
复制代码
From
字段表示用户代理的用户的电子邮箱地址,目的是为了显示搜索引擎用户代理的负责人的电子邮箱联系方式。
From: info@hackr.jp
复制代码
Host
请求头指明了请求的资源所在的服务器主机名和端口号。若是服务器没设置主机名,会发送一个空值。
Host: www.tutu.com
复制代码
像这种If-xxxx
开头的请求头字段,都是条件请求。服务器接收到附带条件的请求后,只判断条件是真时才会执行请求。
If-Match
字段用于和服务器资源的ETag
值作对比时,ETag
值和If-Match
的值相等时才会处理该请求。不然返回412
状态码。经过用星号(*
)的方式,表示只要资源存在就处理请求,但服务器会忽略掉ETag
的值。
If-Match: "123456"
复制代码
If-Modified-Since
用于肯定代理服务器或客户端的资源有效性。在指定的时间以后,请求的资源发生改变时,就处理请求。若是资源都没有改变,则返回304
状态码。
If-Modified-Since: Tue, 13 Apr 2021 12:35:41 GMT
复制代码
If-None-Match
和If-Match
相反,只有服务器资源的ETag
的值和If-None-Match
的值不同时,才会处理该请求。在GET
和HEAD
请求方法中加入该字段能够获取最新的资源。
If-Range
用于告诉服务器,若是If-Range
字段的值和请求资源的ETag
值或时间同样时,就会做为范围请求处理(Range
字段规定请求多少字节的数据)。不然,忽略范围请求,返回所有资源。
If-Range: "123456"
Range: bytes=5001-10000
复制代码
If-Unmodified-Since
字段用来告诉服务器,只有当请求资源在指定的时间以后没有修改的状况下,才会处理请求。若是在指定的时间后发生了修改,则返回412
状态码。
If-Unmodified-Since: Tue, 13 Apr 2021 12:35:41 GMT
复制代码
Proxy-Authorization
字段包含了用户代理提供给代理服务器用于身份验证的凭证。
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
复制代码
Range
请求头字段表示获取资源的哪一部分。服务器收到带有Range
字段的请求后,会在处理请求以后返回206
状态码。若是没法处理,则返回200
状态码并把所有资源返回。
Range: bytes=5001-10000 <!-- bytes=5001-10000为资源的字节 -->
复制代码
Referer
字段表示请求的URL是从哪一个 Web 页面发起的。服务器经过Referer
字段来标识访问来源,进行统计分析、日志记录和缓存优化。
Referer: www.tutu.com <!-- 请求是由www.tutu.com发起的 -->
复制代码
TE
表示客户端可以处理响应的传输编码方式以及优先级。
TE: gzip, deflate;q=0.5
复制代码
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
表示服务器端能处理指定范围内的资源。有两个值:bytes
和none
。none
表示不能处理指定范围内的请求。
Age
表示源服务器再多久前返回过资源。单位为秒。
Age: 3600
复制代码
ETag
表示资源的特定标识符,服务器会给每份资源都分配对应的ETag
值。当资源发生变化时,ETag
值也会改变。例如,访问同一个 URL 的网站同时具有有中英文版,当切换中文时,会返回中文的资源(ETag: user-chi
),而切换到英文时,返回的是英文的资源(ETag: user-us
)。
ETag: "user-123456"
复制代码
ETag
值。字段值最开头会添加W/
的字符ETag: W/"user-123456"
复制代码
Location
字段表示须要将页面重定向到某个地址,通常都是响应码为3xx
的响应才有用。
Location: www.baidu.com <!-- 重定向到www.baidu.com -->
复制代码
Proxy-Authenticate
字段表示获取代理服务器的资源要经过身份验证的方式。
Retry-After
字段表示客户端应该在多久以后再次请求。配合503
和3xx
状态码响应一块儿使用。
Retry-After: 120
复制代码
Server
字段表示处理请求的服务器所用到的软件相关信息。
Server: Apache/2.2.17
复制代码
Vary
字段能够对缓存进行控制。从代理服务器收到源服务器返回含有Vary
指定项的响应后,若是要进行缓存,那么会对请求中含有Vary
指定头部字段的请求返回缓存。即便对相同资源发起请求,若是Vary
指定的头部字段不相同,就必须从源服务器从新获取资源。
Vary: Accept-Language
复制代码
Allow
用于告诉客户端,资源所支持的 HTTP 方法,若是服务器收到不支持的 HTTP 方法时,会返回405
状态码做为响应。
Allow: GET, DELETE
复制代码
Content-Encoding
字段表示服务器对实体的主体部分用的内容编码方式。内容编码在Accept-Encoding
中已经介绍过,一共有4
种。
Content-Encoding: gzip
复制代码
Content-Language
字段表示实体主体使用的天然语言。
Content-Language: zh-CN
复制代码
Content-Length
表示实体主体部分的大小(以字节为单位)。
Content-Length: 1500
复制代码
Content-Location
字段表示要返回数据的地址。
Content-Location: https://www.tutu.com/index.html
复制代码
Content-Range
字段表示的是一个数据片断在整个文件中的位置。
Content-Range: bytes 5001-10000/10000
复制代码
Content-type
字段表示实体主体中对象的媒体类型。
Content-type: text/html; charset=UTF-8
复制代码
Expires
字段会把资源失效的日期告诉客户端。在这个日期后,资源就会过时。也就是说,在指定的日期内能够从浏览器缓存中获取资源。若是超过了这个日期,就必须向服务器发起资源请求。若是头部存在Cache-Control: max-age
时,会优先处理max-age
指令。
Expires: Tue, 13 Apr 2021 12:35:41 GMT
复制代码
Last-Modified
字段表示资源最后修改的时间。
Last-Modified: Tue, 13 Apr 2021 12:35:41 GMT
复制代码
HTTP 缓存可分为强缓存和协商缓存,主要用于加快资源的获取速度,提升用户体验,减小网络链接,缓解服务器压力。
对强缓存来讲,浏览器会判断请求的资源是否在有效期内。若是是在有效期内,就直接从缓存中读取资源,不用向服务器发送资源请求。强缓存经过Expires
、Cache-Control
和Pragma
这三个头部字段设置。
Cache-Control
头部字段在上面也详细介绍过在各端所具有的属性值。下面来列出最多见的几个值。
public
: 该资源能够被浏览器和代理服务器进行缓存。private
: 该资源只能够被浏览器缓存,其余都不能够。no-cache
: 不使用强缓存,强制向源服务器再次验证缓存的有效性。这个值表示走协商缓存。no-store
: 不使用任何缓存,每次都向源服务器获取最新资源。max-age
: 若是缓存的资源没有超过规定的时间,客户端就从缓存中获取资源。以秒为单位。s-maxage
: 只适用于代理服务器,表示代理服务器中的资源过时时长,用了s-maxage
后,会忽略max-age
和Expires
字段。Expires
字段的值是一个GMT
格式的时间日期,将资源失效的日期告诉客户端,客户端收到带有该字段的响应体后进行缓存。后续客户端发起相同的资源请求,会用Expires
的值和本地时间作对比,若是该请求的本地时间小于Expires
的值,就直接用缓存中的资源,不用向服务器发起请求。
Expires
的值会产生一个问题。若是修改了本地时间,就会致使客户端和服务器端的时间不一致,那么对于缓存过时的判断就没法和预期同样了。
Expires
在三者中优先级最低。
Pragma
能够看上面的介绍,这里不过多讲解。
强缓存在 Chrome 中会返回200
状态码而且有两种状况。
memory cache
: 只要页面不关闭,就会从浏览器内存中获取资源。disk cache
: 从磁盘中读取缓存资源。用了强缓存后,若是服务器端的资源更新了,客户端是不知道的,并且在过时以前都会用缓存中的资源。能够经过Ctrl
+ F5
强制刷新。
协商缓存是在用本地缓存以前,会向服务器发起一次GET
请求,验证浏览器保存在本地的资源是否过时。
通常状况下是用请求资源的最近一次修改时间戳来判断。来举个例子:假设客户端向服务器端请求一个文件,为了让资源被再次请求时能经过协商缓存机制使用本地缓存。首次返回该资源的响应头中会包含一个last-modified
的字段,字段的值表示资源最后修改的时间。当刷新页面时,该资源使用的是协商缓存,浏览器没法确认本地缓存是否过时,而后向服务器发起一次GET
请求,进行缓存有效性的协商,本次请求的请求头中包含一个if-modified-since
字段,字段的值是上次响应头中的last-modified
字段的值。
last-modified
存在两个缺陷:
为了弥补经过时间判断的不足,HTTP 1.1 加入了ETag
(实体标签)的头信息。
ETag
表示资源的特定标识符,相似文件指纹。做用上面也有提到,这里不过多讲解。
当响应头同时存在last-modified
和ETag
这两个字段时,会以ETag
为准。再次对该资源发起请求时,会将以前的响应头中ETag
的值看成此次请求中if-none-match
字段的值,发送给服务器进行缓存有效性验证。若是验证缓存有效,就返回304
状态码响应重定向到本地缓存。
ETag
的出现并非last-modified
的代替品,而是一种补充方案,它仍是存在弊端的。
ETag
的过程会影响到服务器的性能。ETag
还分强ETag
和弱ETag
。
ETag
值是根据资源内容进行生成,保证每一个字节都相同。ETag
值是根据资源的部分属性值来生成,生成速度快可是没法保证每一个字节都相同。若是浏览器走的是协商缓存,而且资源没发生改变,服务器端会返回304
状态响应码告诉浏览器获取本地缓存的资源便可。
HTTP协议主要的不足之处有如下几点。
HTTP 协议自己没有加密功能,因此没法作到对通讯请求和响应内容进行加密。
因为 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 服务器设置限制访问的前提下)。也就是来者不拒。
虽然使用 HTTP 协议没法肯定通讯方,但使用 SSL 能够。SSL 除了加密处理外,还用了一种证书的手段,用于确认通讯方。证书是由值得信任的第三方机构颁发,用来证实服务器和客户端是真实存在的。
经过证书,以证实通讯方就是意料中的服务器,对我的来讲,减小了我的信息泄露的危险。另外,客户端持有证书便可完成我的身份的确认,也可用于对 Web 网站的认证环节。
没有任何办法确认,发出去的请求或响应和接收到的请求或响应是先后相同的。有可能在中途被篡改为其余的内容,即便内容是真的被改了,接收方也不会知道。
可使用 MD5 和 SHA-1 等散列值校验方法,以及用来确认文件的数字签名方法(PGP签名)对内容进行加密。可是用这些方法也没法保证正确,由于 MD5 和 PGP 自己被修改的话,用户也不会知道。
HTTP加上加密处理和认证以及完整性保护机制就是HTTPS
HTTPS 不是应用层的一种新协议。只是 HTTP 通讯接口部分用 SSL 和 TLS 协议代替而已。以前是 HTTP 和 TCP 进行通讯,用了 SSL 以后,就变成了 HTTP 先和 SSL 通讯,以后 SSL 和 TCP 通讯。
使用 SSL 以后,HTTP 就有了 HTTPS 的加密、证书和完整保护性这些功能。
SSL 用的是公开密钥加密的处理方式。加密方法中的加密算法是公开的,密钥则是保密的。经过这种方式能够保持加密方法的安全性。
加密和解密都会用到密钥。没有密钥就没办法对密码解密,任何人只要有密钥就能够进行解密,若是密钥被攻击者得到,那么加密也就没有意义了。
加密和解密同用一个密钥的方式叫作共享密钥加密,也称为对称密钥加密。也就是说,客户端和服务器端共用一个密钥对消息进行加密。客户端在发送请求时,会用密钥对消息加密。服务器收到后,再用密钥对消息进行解密。
对称加密虽然保证了消息保密性,但客户端和服务器端用的都是同一个密钥,若是说在传输的过程当中出现了中间人或攻击者。密钥就有可能落到攻击者手中,这样就对消息加密就没有什么意义了。
非对称加密解决了对称加密的缺点。非对称加密用的是一对非对称的密钥。一把叫作私有密钥,另外一把叫作公开密钥。私有密钥只能是本身所拥有,而公开密钥则是任何人均可以拿到。
当客户端发送消息前,使用公共密钥进行加密,而服务器收到消息后,使用私有密钥进行解密。
非对称加密须要在发送端在发送消息时,用公钥加密。但公钥是任何人均可以拿到,中间人也能够。中间人虽然不知道接收方的私钥是什么,但能够截获发送端的公钥,本身另外生成一把公钥或者篡改公钥,把公钥发给接收端。并且非对称加密处理起来比对称加密的方式更加复杂,这样就致使了效率变低。
HTTPS 用的就是对称加密和非对称加密二者的混合加密。使用对称加密的好处是解密效率快,使用非对称加密的好处是在传输消息的过程当中不会被破解。即便截获了数据,没有对应的私钥,也没法对消息进行破解。
数字摘要是采用 Hash 函数将须要加密的明文 “摘要” 成一串固定长度(128
位)的密文,这串密文又称为数字指纹,它有固定长度,并且不一样的明文摘要成密文,其结果老是不一样,而一样的明文摘要必须一致。数字摘要是 HTTPS 能确保数据完整性和防篡改的根本缘由。
数字签名是非对称加密和数字摘要两项技术的应用,它将摘要信息用发送者的私钥加密,和原文一块儿发给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,而后用 Hash 函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。若是同样,那就说明收到的信息是完整的。不然说明信息被修改过,所以数字签名可以验证信息的完整性。
数字签名是附加在报文上的特殊加密校验码。使用数字签名有如下两点好处。
数字签名的过程以下: 明文 -> hash运算 -> 摘要 -> 私钥加密 -> 数字签名
数字证书(CA)就像咱们的身份证同样,信息都是惟一性的。它是属于可信任的一些第三方机构全部。证书包含了如下的信息。
数字证书还包括对象的公钥,对象和所用签名算法的描述信息。全部人均可以建立一个数字证书,但并非全部人都能得到签发权,从而为证书信息担保,并用它私有密钥签发证书。
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 安全就没有问题了。其实它仍是存在一些问题的。在使用 SSL 时,它的处理速度会变慢。其缘由有两种,一是通讯慢,二是每次都进行加密通讯,就致使消耗大量的 CPU 和内存资源,致使处理速度变慢。
固然能够用 SSL 加速(专用服务器)硬件来改善效率的问题。能够提升 SSL 的计算速度,分担负载。但只有在 SSL 处理时才发挥 SSL 加速器的效果。像一些非敏感的信息就用 HTTP 进行通讯,对于敏感信息采用 HTTPS 通讯,以节约资源。
80
,后者是 443
。HTTP 1.x主要有如下几个缺点:
SPDY 是由谷歌开发的基于 TCP 协议的应用层协议。目标是为了优化 HTTP 协议的性能,经过压缩、多路复用和优先级技术,缩短网页的加载时间并提升安全性。SPDY 协议的核心思想是尽可能减小 TCP 的链接数。SPDY 并非一种代替 HTTP 的协议,而是对 HTTP 协议的加强。
SPDY 没有改写 HTTP 协议,而是在 TCP/IP的应用层和传输层之间经过新加会话层的形式运做。同时,考虑到安全问题,SPDY 规定通讯中使用 SSL。
SPDY 以会话层的形式加入,控制对数据的流动,但仍是采用 HTTP 创建通讯。所以,能够照常使用 HTTP 的请求方法、Cookie 以及 HTTP 报文等等。
HTTP 2.0 能够说是 SPDY 的升级版(实际上是基于 SPDY 设计的),但HTTP 2.0和 SPDY 仍是存在一些不一样的。主要有如下两点:
下面就简单的介绍一下 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性能权威指南》这本书,里面讲得挺详细的。
网络架构模型除了TCP/IP模型以外,还有OSI模型。OSI模型其实是多了三层。
也就是上面所说的多加了 SSL 和 SPDY 这两个协议(都处于应用层)。
而数据链路层细分的话有两层:
前面也说到,HTTP 是无状态的协议,它不会对以前发送过的请求和响应的状态进行管理。假设,客户端的用户发送一个请求,服务器端收到请求后想知道这个请求是哪一个家伙发过来的,那么就要有一个状态进行管理。而Cookie
正是解决这类问题而出现。
从服务器端返回的响应头信息中有一个Set-Cookie
的字段信息,告诉客户端保存Cookie
。在下次客户端向服务器端发送请求时,客户端会自动在请求头信息中加入Cookie
的值发送出去。
服务器收到客户端发送过来的Cookie
以后,会检查究竟是从哪一个客户端发送过的请求,而后对比服务器上的记录,最后获得了以前的状态信息。
Set-Cookie
是属于响应头中的一个字段,它包含如下的值。
NAME=VALUE
: Cookie
的名称和值。expires=DATE
: Cookie
的有效期。path=PATH
: 把服务器上的文件目录做为Cookie
的使用对象,若是没有设置,默认是文档所在的文件目录。domain=域名
: 做为Cookie
适用对象的域名,若是没有设置,默认是建立Cookie
的服务器的域名。Secure
: 只有在 HTTPS 时才会发送Cookie
。HttpOnly
: JavaScript 不能访问Cookie
。主要是为了防止跨站脚本攻击时Cookie
的信息窃取。Cookie
是请求头中的一个字段,它包含服务器经过Set-Cookie
头部设置并存到客户端的值。若是接收多个Cookie
时,能够以多个Cookie
形式发送回去。
以上是我一个多月在学 HTTP 相关书籍作的一些笔记。哪里有不对的地方,请各位大佬多多指点!固然文章对你有所帮助,欢迎点赞加关注哦!