HTTP
是超文本传输协议,用于客户端和服务器端之间的通讯,属于TCP/IP
中的应用层。css
客户端是服务请求方,服务器端是服务提供方。html
URI:URI是统一资源标识符;java
URL:是统一资源定位器;web
URI的格式(了解便可)
[scheme:][//user:password@]host[:port][/path][?query][#fragment]
如上是URI的具体格式,下面介绍其意义:算法
scheme:
:是协议方案,好比http:
,https:
,file:
等,此项可选可不选[//[user:password@]
:指定用户名和密码做为从服务器获取资源时必要的登录信息,此项是可选项host
:服务器地址,例如www.runoob.com
[:port]
:服务器端口号,例如:8080,此项是可选项[/path]
:指定服务器上的文件路径来定位特指的资源[?query]
:查询字符串,例如?id=123&pas=123
[#fragment]
:片断标识符
见DNS基础知识json
如图:浏览器
HTTP 是无状态协议,它不对以前发生过的请求和响应的状态进行管理。也就是说,没法根据以前的状态进行本次的请求处理。缓存
假设要求登陆认证的 Web 页面自己没法进行状态的管理(不记录已 登陆的状态),那么每次跳转新页面不是要再次登陆,就是要在每次 请求报文中附加参数来管理登陆状态。安全
HTTP使用 Cookie 的状态管理,Cookie 技术经过在请求和响应报文中写入 Cookie 信 息来控制客户端的状态。服务器
Cookie
会根据从服务器端发送的响应报文内的一个叫作 Set-Cookie
的首部字段信息,通知客户端保存Cookie
。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie
值后发送出 去。服务器端发现客户端发送过来的 Cookie
后,会去检查到底是从哪一 个客户端发来的链接请求,而后对比服务器上的记录,最后获得以前 的状态信息。
以下图:
HTTP报文
是HTTP请求和响应的单位。用于请求的报文叫作请求报文
,而用于响应的报文叫作 响应报文
。
报文主体和实体主体的差别 :
实体做为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。HTTP 报文的主体用于传输请求或响应的实体主体。 一般,报文主体等于实体主体。只有当传输中进行编码操做时,实体 主体的内容发生变化,才致使它和报文主体产生差别
首部字段名: 字段值
若是有多个值,则首部字段名: 字段值1, 字段值2
若是HTTP首部字段重复了会如何?
当HTTP报文首部中出现中出现了两个或两个以上具备相同首部字段名时会怎么样?这种状况 在规范中还没有明确,根据浏览器内部处理逻辑的不一样,结果可能并不一致。
HTTP首部字段分为四个部分:
如今以请求菜鸟教程的报文为例来进行分析:
请求报文
GET /HTTP/1.1 //请求行
Host: www.runoob.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate, br Referer: https://cn.bing.com/ Connection: keep-alive Cookie: Hm_lvt_3eec0b7da6548cf07db3bc477ea905ee=1554627142,1556799533; _ga=GA1.2.579069872.1554627144; Hm_lpvt_3eec0b7da6548cf07db3bc477ea905ee=1556799533; _gid=GA1.2.1514513796.1556799533; _gat_gtag_UA_84264393_2=1 Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0 复制代码
响应报文
HTTP/1.1 200 OK //状态行
Server: Tengine
Content-Type: text/html
Content-Length: 150124
Connection: keep-alive
Date: Thu, 02 May 2019 09:27:08 GMT
Content-Encoding: gzip
Vary: Accept-Encoding
X-M-Log: QNM:xs446;QNM3:1
X-M-Reqid: jVAAADsHtCKO05oV
X-Powered-By: HHVM/3.28.1
X-Qnm-Cache: Hit
Ali-Swift-Global-Savetime: 1556270140
Via: cache16.l2cn1807[0,200-0,H], cache37.l2cn1807[1,0], cache9.cn1066[0,200-0,H], cache5.cn1066[1,0]
Age: 10328
X-Cache: HIT TCP_MEM_HIT dirn:11:466942761
X-Swift-SaveTime: Thu, 02 May 2019 10:36:54 GMT
X-Swift-CacheTime: 86400
Timing-Allow-Origin: *
EagleId: db971b1915567995564074785e
复制代码
请求行:请求行中包含用于请求的方法,请求的URI和HTTP版本
状态行:状态行包含响应结果的状态码,缘由短语和HTTP版本
在请求报文中GET /HTTP/1.1
是请求行,其中GET
表明请求的方法,/HTTP/1.1
表明HTTP版本,在这个请求中未出现请求的URI
。
在响应报文中HTTP/1.1 200 OK
是状态行,其中HTTP/1.1
是请求的版本,200
是响应结果的状态码,而OK
则是缘由短语。
GET:GET方法用来访问以被URI识别的资源。指定的资源经服务器解析后返回响应的内容。以下图
POST: POST方法用来传输实体的主体。以下图
其余方法如PUT HEAD DELETE OPTIONS TRACE CONNECT
通常不使用。下面简单介绍一下:
方法 | 做用 | 不使用的缘由 |
---|---|---|
PUT | 用来传输文件 | PUT方法不采用任何验证机制,存在安全问题 |
HEAD | 和GET方法同样,不过只返回响应首部 | --- |
DELETE | 用来删除文件 | DELETE不采用任何验证机制,存在安全问题 |
OPTIONS | 查询针对请求URI指定的资源支持的方法 | ---- |
TRACE | 让WEB服务器端将以前的请求通讯返回给客户端 | 容易引起跨站追踪(XST)攻击 |
CONNECT | 要求在与代理服务器通讯时创建隧道,实现用隧道协议进行TCP通讯 | ---- |
表示从客户端发来的请求在服务器端被正常处理了
该状态码表明服务器接收的请求已经被成功处理,可是返回的响应报文中不包含实体的主体部分
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求
永久性重定向,该状态码表示请求的资源已被分配到新的URI,之后应该 使用如今所指的URI。
临时重定向。该状态码代表请求的资源已被分配了新的URI,但愿用户本次能使用新的URI访问。
该状态码表示因为请求资源存在另外一个URI,应该使用GET方法定向获取请求的资源
该状态码表示客户端发送附带条件请求时,服务器端容许请求访问资源,但由于请求未知足条件的状况后, 直接返回304.
临时重定向,和302类似。可是307不会从Post变成GET
该状态码表示请求报文中存在语法错误。当错误发生时,须要修改请求的内容后再次发送请求
该状态码表示发送的请求须要经过HTTP认证的认证信息。另外若以前已经进行过一次请求,则表示用户认证失败
该状态码代表对请求资源的访问被服务器拒绝了
该状态码代表服务器上没法找到请求的资源
该主题码表示服务器在执行请求时发生了错误
该状态码代表服务器暂时处于超负载或正在进行停机维护,如今没法处理请求。
HTTP/1.1定义了以下47种首部地段,以下
通用首部字段:
请求首部字段:
响应首部字段:
实体首部字段:
非HTTP/1.1首部字段(不属于47种中的字段):Cookie
、 Set-Cookie
、 Content-Disposition
等。
HTTP将使用 缓存代理
和非缓存代理
的首部字段分红两种类型:端到端首部(End-to-end Header)、逐跳首部(Hop-by-hop Header)
缓存代理
代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本 (缓存)保存在代理服务器上。 当代理再次接收到对相同资源的请求时,就能够不从源服务器那里获 取资源,而是将以前缓存的资源做为响应返回。
透明代理
转发请求或响应时,不对报文作任何加工的代理类型被称为透明代理 (Transparent Proxy)。反之,对报文内容进行加工的代理被称为非 透明代理。
注意:这里的非缓存代理不等于透明代理;它们划分的标准不同。`缓存代理`和`非缓存代理`是经过是否使用缓存来划分的;而`透明代理`和`非透明代理`是经过是否会修改报文来划分。
端到端首部:分在此类别中的首部会转发给请求/响应对应的最终接收目标(即全程有效),且必须保存在由缓存生成的响应中,另外规定它必须被转发
逐跳首部:分在此类别的首部只对单次转发有效,会由于经过缓存或代理而再也不转发。在HTTP/1.1和之后版本中,若是要使用逐跳首部,须要经过Connection首部字段
逐跳首部字段为:
其余字段都为端到端首部
在实例的请求报文中出现的通用首部
Connection: keep-alive
Cache-Control: max-age=0
复制代码
在实例的响应报文中出现的通用首部
Connection: keep-alive
Date: Thu, 02 May 2019 09:27:08 GMT
Via: cache16.l2cn1807[0,200-0,H], cache37.l2cn1807[1,0], cache9.cn1066[0,200-0,H], cache5.cn1066[1,0]
复制代码
经过指定首部字段Cathe-Control的指令,就能够操做缓存的工做机制,如图:
请求报文中Cache-Control: max-age=0
表示缓存服务器一般须要将请求转发给源服务器。
Connection
的做用:
代理服务器的基本行为就是接收客户端发送的请求后转发给其余服务器。代理不改变请求 URI,会直接发送给前方持有资源的目标服务器。上面介绍的缓存代理是代理服务器做用的一种。
Connection: close //代表服务器想断开链接
Connection: Keep-Alive //保持持久化链接(默认)
复制代码
用来追踪客户端与服务器端之间的请求和响应报文的传输路径。
如Via: cache16.l2cn1807[0,200-0,H], cache37.l2cn1807[1,0], cache9.cn1066[0,200-0,H], cache5.cn1066[1,0]
首部字段Date代表建立HTTP报文的时间,如Date: Thu, 02 May 2019 09:27:08 GMT
就表示建立报文的时间为2019年5月2日,星期二。
Pragma是历史遗留字段,仅做为与HTTP/1.0的向后兼容而定义。
用来讲明在报文主体后记录了哪些首部字段
规定传输报文主体时采用的编码方式(仅对分块传输编码有效)
用来检测HTTP协议及其余协议是否可以使用更高的版本进行通讯。
告诉用户一些与缓存有关的问题的警告
请求报文(去除了通用首部字段)
Host: www.runoob.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Referer: https://cn.bing.com/
Cookie: Hm_lvt_3eec0b7da6548cf07db3bc477ea905ee=1554627142,1556799533; _ga=GA1.2.579069872.1554627144; Hm_lpvt_3eec0b7da6548cf07db3bc477ea905ee=1556799533; _gid=GA1.2.1514513796.1556799533; _gat_gtag_UA_84264393_2=1
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
复制代码
告诉服务器请求的资源所处的互联网主机名和端口号,如Host: www.runoob.com
。Host是惟一必须包含在请求内的首部字段
用来将建立请求的浏览器和用户代理名称等信息传达给服务器。
例如上面的请求首部:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
通知服务器能够处理的媒体类型及媒体类型的相对优先级
例如Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
文本文件
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
使用q=
来额外表示权重值,用;
进行分隔。权重值的范围是0~1(可精确到小数点后3位),且1为最大值。不指定 权重值时,默认权重为q=1.0.当服务器提供多个内容时会首先返回权重值最高的媒体类型。
Accept-Charset
首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外可一次性指定多种字符集。与首部字段 Accept
相同的可用权重q值来表示相对优先级
Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码,可用权重q来指定优先级 例如Accept-Encoding: gzip, deflate, br
首部字段Accept-Language用来告诉服务器用户代理可以处理的语言,能够指定多个语言,可使用q来决定优先级。 例如Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
用来告诉服务器,用户代理的认证信息
告知服务器指望出现某种特定的行为
告诉服务器使用用户代理的用户的电子邮箱地址
告诉服务器匹配资源所用的实体标记(ETag)值,服务器会对比If-Match的字段值和资源的ETag值,仅 当二者一致时才执行请求.反之则返回状码412
告诉服务器若If-Modified-Since字段值早于资源更新的时间,则但愿能处理该请求。 反之若是在If-Modified-Since指定的时间日期以后,若是请求的资源都没有更新,则 返回的状态码 304
与If-Match相反
告诉服务器若指定的If-Range字段值(ETag值或者时间)和请求资源的ETag值或时间相一致时,则做为范围请求处理。 反之,则返回全体资源。如图:
与If-Modified-Since做用相反
对于只需获取部分资源的范围请求,包含首部字段Range
便可告知服务器资源的指定范围。 接收到附带Range
首部字段请求的服务器,会在处理请求以后返回206
.没法处理该范围的 请求时,则会返回200
的响应及所有资源。
告诉服务器请求的原始URI
例如:Referer: https://cn.bing.com/
说明我是从微软必应请求的
Upgrade-Insecure-Requests
是一个请求首部,用来向服务器端发送信号,表示客户端优先选择加密及带有身份验证的响应。不属于47种报文首部字段。
告诉服务器,客户端可以处理的传输编码方式及相对优先级
很显然,Transfer-Encoding
和TE
是一组,Content-Encoding
和Accept-Encoding
是一组。 根本区别在于,Content-Encoding
和Accept-Encoding
限制的是报文主体在整个传输过程当中使用的编码方式,全局有效;Transfer-Encoding
和TE
限制的是报文主体在两个节点间(源服务器和代理服务器之间、代理服务器和客户端之间等)传输时使用的编码方式,只在两节点间有效。
转自区分Transfer-Encoding,TE,Content-Encoding,Accept-Encoding四个首部字段
响应报文
Server: Tengine
Vary: Accept-Encoding
X-M-Log: QNM:xs446;QNM3:1
X-M-Reqid: jVAAADsHtCKO05oV
X-Powered-By: HHVM/3.28.1
X-Qnm-Cache: Hit
Ali-Swift-Global-Savetime: 1556270140
Age: 10328
X-Cache: HIT TCP_MEM_HIT dirn:11:466942761
X-Swift-SaveTime: Thu, 02 May 2019 10:36:54 GMT
X-Swift-CacheTime: 86400
Timing-Allow-Origin: *
EagleId: db971b1915567995564074785e
复制代码
首部字段Accept-Ranges是用来告诉客户端服务器是否能处理范围请求,以指定获取服务器端 某个部分的资源。能够指定的值为bytes
(表示接受范围请求)和none
(表示不接受范围请求).
告诉客户端,源服务器在多久前建立了响应。字段值的单位为秒。
主要用于检验缓存是否改变。它告诉客户端实体标识,是一种可将资源以字符串的形式作惟一标识的方式。服务器会为每份资源分配对应的ETag值
另外当资源更新时,ETag值也须要更新。当资源被缓存时,就会被分配惟一的标识。若在下载过程当中 出现链接的中断,再链接的状况,都会依照ETag值来指定资源。
ETag中有强ETag值和弱ETag值
强ETag值,不管实体发生多么细微的变化都会改变其值。
弱ETag值,只用于提示资源是否相同。只有资源发生了根本改变,产生差别时才会改变ETag
值。这时, 会在字段值最开始处附加 W/
将响应接受方引领到某个与请求URI位置不一样的资源。基本上,该字段会配合3XX的响应,提供重定向的URI。
会把由代理服务器所要求的认证信息发生给客户端
告诉客户端应该在多久以后再发送请求。主要配合状态码503响应或3xx响应一块儿使用。字段值能够指定为具体的日期时间,也能够是建立响应后的秒数
告诉客户端当前服务器上安装的HTTP服务器应用程序的信息
对缓存进行控制。具体见这里
用于HTTP访问认证
告诉客户端支持的请求方法
告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩
主要采用如下4种内容编码的方式
告诉客户端,实体使用的语言
代表实体主体部分的大小,单位是字节。对实体主体进行内容编码传输时,不能再使用Content-Length 首部字段
给出报文主体部分相对应的URI。和首部字段Location不一样,Content-Location表示的是报文主体返回资源对应的URI
首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于检 查报文主体在传输过程当中是否保持完整,以及确认传输到达。
针对范围请求,返回响应时使用的首部字段Content-Range,能告诉客户端做为响应返回的实体的哪一个部分 符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。
说明实体主体内对象的媒体类型,和首部字段Accept
同样,字段值用type/subtype
形式赋值
Http Header
里的Content-Type
通常有这三种:
form的enctype属性为编码方式,经常使用有两种:
application/x-www-form-urlencoded
和multipart/form-data
,默认为application/x-www-form-urlencoded
。
当action
为get
时候,浏览器用x-www-form-urlencoded
的编码方式把form
数据转换成一个字串(name1=value1&name2=value2...)
,而后把这个字串追加到url后面,用?分割,加载这个新的url。
当action
为post
时候,浏览器把form
数据封装到http body
中,而后发送到server
。 若是没有type=file
的控件,用默认的application/x-www-form-urlencoded
就能够了。 可是若是有type=file
的话,就要用到multipart/form-data
了。
当action
为post
且Content-Type
类型是multipart/form-data
,浏览器会把整个表单以控件为单位分割,并为每一个部分加上Content-Disposition
(form-data或者file),Content-Type
(默认为text/plain
),name
(控件name)等信息,并加上分割符。
会将资源失效的日期告诉客户端
指明资源最终修改的时间
开始状态管理所使用的Cookie信息(响应首部字段)
告诉服务器,当客户端想获取HTTP状态管理支持时,就会在请求中包含从服务器接受到的Cookie。接收到多个 Cookie时,同时能够以多个Cookie形式发送
HTTP首部字段是能够自行扩展的。因此在WEB服务器和浏览器应用上,会出现各类非标准的首部字段
属于响应首部,用于控制网站内容在其余web网站的Frame标签内的显示问题。其主要目的是为了防止 点击劫持攻击
有两个可指定的字段值 DENY:拒绝 SAMEORIGIN:仅在同源域名下的页面匹配时许可
属于响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器XSS防御机制开关。
字段值: 0:将XSS过滤设置为无效状态 1:将XSS过滤设置为有效状态
属于请求字段,意味拒绝我的信息被采集,是表示拒绝被精准广告追踪的一种方法
字段值 0:赞成被追踪 1:拒绝被追踪
属于响应首部,经过利用 P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,可让 Web 网站上 的我的隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的 目的。
在HTTP等多种协议中,经过给非标准参数加上前缀X-,来区别于标准参数,并使那些非标准参数做为扩展变成可能(如上面的响应首部)。可是这种简单粗暴的作法没有任何好处,所以被提议中止。然而对已经在使用中的X-前缀来讲,不该该要求其变动。
HTTP+ 加密 + 认证 + 完整性保护 =HTTPS
HTTPS 并不是是应用层的一种新协议。只是 HTTP 通讯接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代 替而已。 一般,HTTP 直接和 TCP 通讯。当使用 SSL 时,则演变成先和 SSL 通 信,再由 SSL 和 TCP 通讯了。简言之,所谓 HTTPS,其实就是身披 SSL 协议这层外壳的 HTTP
在采用 SSL 后,HTTP 就拥有了 HTTPS 的加密、证书和完整性保护 这些功能。
SSL 是独立于 HTTP 的协议,因此不光是 HTTP 协议,其余运行在应 用层的 SMTP 和 Telnet 等协议都可配合 SSL 协议使用。能够说 SSL 是 当今世界上应用最为普遍的网络安全技术。
加密和解密同用一个密钥的方式称为共享密钥加密(Common key crypto system),也被叫作对称密钥加密
共享密钥加密的困境
以共享密钥方式加密时必须将密钥也发给对方。可究竟怎样才能 安全地转交?在互联网上转发密钥时,若是通讯被监听那么密钥 就可会落入攻击者之手,同时也就失去了加密的意义。另外还得 设法安全地保管接收到的密钥。
公开密钥加密使用一对非对称的密钥。一把叫作私有密钥 (private key),另外一把叫作公开密钥(public key)。顾名思 义,私有密钥不能让其余任何人知道,而公开密钥则能够随意发 布,任何人均可以得到。
HTTPS 采用共享密钥加密和公开密钥加密二者并用的混合加密 机制。若密钥可以实现安全交换,那么有可能会考虑仅使用公开 密钥加密来通讯。
可是公开密钥加密与共享密钥加密相比,其处 理速度要慢。 因此应充分利用二者各自的优点,将多种方法组合起来用于通 信。在交换密钥环节使用公开密钥加密方式,以后的创建通讯交 换报文阶段则使用共享密钥加密方式。
遗憾的是,公开密钥加密方式仍是存在一些问题的。那就是没法证实 公开密钥自己就是货真价实的公开密钥。好比,正准备和某台服务器 创建公开密钥加密方式下的通讯时,如何证实收到的公开密钥就是原 本预想的那台服务器发行的公开密钥。或许在公开密钥传输途中,真 正的公开密钥已经被攻击者替换掉了。
为了解决上述问题,可使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书
服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端, 以进行公开密钥加密方式通讯。
公钥证书也可叫作数字证书或直接称 为证书。 接到证书的客户端可以使用数字证书认证机构的公开密钥,对那张证书 上的数字签名进行验证,一旦验证经过,客户端即可明确两件事:
此处认证机关的公开密钥必须安全地转交给客户端。使用通讯方式 时,如何安全转交是一件很困难的事,所以,多数浏览器开发商发布 版本时,会事先在内部植入经常使用认证机关的公开密钥。
SSL 和 TLS HTTPS 使用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security)这两个协议。 SSL 技术最初是由浏览器开发商网景通讯公司率先倡导的,开发 过 SSL3.0 以前的版本。目前主导权已转移到 IETF(Internet Engineering Task Force,Internet 工程任务组)的手中。 IETF 以 SSL3.0 为基准,后又制定了 TLS1.0、TLS1.1 和 TLS1.2。TSL 是以 SSL 为原型开发的协议,有时会统一称该协议 为 SSL。当前主流的版本是 SSL3.0 和 TLS1.0。 因为 SSL1.0 协议在设计之初被发现出了问题,就没有实际投入 使用。SSL2.0 也被发现存在问题,因此不少浏览器直接废除了 该协议版本。