你要的HTTP协议上

5次阅读

共计 9424 个字符,预计需要花费 24 分钟才能阅读完成。

协议是指规则(如:如何探测到通信目标,由哪一边发起通信,使用哪种语言通信,怎样结束通信等规则)的约定。web 建立在 HTTP 协议(超文本传输协议)之上通信的。

1. 最初的设计理念:借助多文档之间相互关联形成的超文本,连成可相互参阅的 WWW(World wide web)。能够让远隔两地的研究者们共享知识。于是提出三项构建技术:HTML(页面的文本语言)、HTTP(作为文档传递的协议)、URL(统一资源定位符,制定文档所在的地址)。

2. 发送端:应用层 (HTTP 报文) –> 传输层(将 HTTP 报文分割并给每部分加上传输层首部变为 TCP 报文) –> 网络层(给 TCP 报文加上网络层首部变成 IP 报文) –> 数据链路层(给 IP 报文加以太网首部成为最终报文)
接收端:数据链路层(去掉以太网首部) –> 网络层(去掉网络层首部) –> 传输层(去掉传输层首部) –> 应用层(接收到最终的 HTTP 请求)

3. 可靠的字节流服务:
字节流服务:将大块数据分割为以报文段为单位的数据包进行管理。
可靠:能够把数据准备无误的传输给对方(采用三次握手策略来保证)
TCP 协议的三次握手:发送端发送带有 SYN(synchronize)标志的数据包给接收端。接收端收到后回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。最后发送端再发送一个带有 ACK 标志的数据包代表握手结束。

4.DNS:位于应用层的协议,提供通过域名查找 IP 地址,也可以通过 IP 地址逆向反查域名的服务。

5. 客户端发送请求报文,请求报文由请求行(包括请求方法、请求 URI 和 HTTP 协议版本)、请求首部字段(包含通用首部、请求首部、实体首部)和内容实体构成。
服务器端接收到请求后以响应的形式返回,响应报文由状态行(包含响应状态的状态码、原因短语和 HTTP 版本)、响应首部字段(包含通用首部、响应首部、实体首部)以及响应实体构成。
这两种报文的前两部分都属于报文头部信息,实体内容属于报文实体,报文头部和报文实体之间以空行隔开(CR+LF)。一些说明如下:
1)通用首部:请求和响应双方都会用到的首部
2) 实体首部:针对请求和响应报文的实体部分使用的首部,补充了资源内容更新时间等与实体有关的信息。

6.HTTP 是一种不保存状态(无状态)的协议,其并不对请求和响应之间的通信状态进行保存,也不对发送过的请求和响应做持久化处理。这是为了快速的处理大量的事务,确保协议的可伸缩性。

7. 持久连接:
在 http 协议的初始版本中,每进行一次 HTTP 请求就要连接并断开一次 TCP,到下次请求的时候再次进行一次 TCP 连接与断开。现如今传输的内容越来越多,为了减少服务器的负荷,http 便提出了持久连接的想法。其指在任意一端没有明确断开连接,则保持 TCP 连接状态。(请求头的 connection:keep-alive 字段)减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器的负荷。

8. 管线化:同时并发的发送多个请求,而不需要一个接一个地等待响应了。

9. 报文主体和实体主体:
报文这是通信中的基本单位,由 8 位组字节流组成
实体是有效的载荷数据,其内容由首部和主体组成,这是两者之间的概念的区别,但是实际上二者指的是同一个东西,只有在对其进行编码时主体的内容发生了变化后两者会产生差异

10.HTTP 状态码描述返回的请求结果。状态码以三位数字和原因短语组成,数字中的第一位指定了响应类别,后两位无分类。响应类型有 5 种

1XX(信息性状态码):接收的请求正在处理
2XX(成功状态码):请求正常处理完毕
3XX(重定向状态码):需要进行附加操作以完成请求
4XX(客户端错误状态码):服务器无法处理请求
5XX(服务器错误状态码):服务器处理请求出错

以下说明常用得分几种状态码:204:请求已被成功处理,但没有资源可返回(一般用于只需要从客户端发送请求至服务器端,而不需要对客户端发送新信息内容的情况下使用)206:表示客户端进行了范围请求,且服务器端成功处理了这部分请求。响应报文中包含 Content-Range 指定范围的实体内容

301:永久性重定向。表示请求的资源已经被重新分配了 URI。如:请求 http://test.com/user 的 URI 时忘记给最后加 '/' 就会产生 301 的状态码
302:临时性重定向。希望本次请求能够使用新的 URI 请求。303:请求对应着一个新的 URI,应该使用 GET 请求重新请求。与 302 有着相同的功能,但明确表示应该使用 GET 请求
301/302/303 状态码很多浏览器都会将请求方法改为 GET 并删除报文内的主体,虽然标准规定 301 和 302 禁止改变请求方法,但实际使用时大多浏览器都这么做
304:客户端发送附带条件的请求,服务器端允许请求访问资源,且服务器端的资源并未改变,可以使用客户端缓存。此状态码返回时不包含任何响应主体
附带条件的请求表示请求头中包含:if-Match、if-None-Match、if-Modified-Since、if-Range。if-Unmodified-Since 中任一个字段的请求
307:临时重定向。与 302 有着相同的含义,但遵守浏览器标准,不会改为 GET 请求

400:表示请求报文中存在语法错误,予以有误或者请求参数不正确
401:表示请求需要有通过 HTTP 认证呢过的认证信息,若之前请求过一次则表示用户认证失败,浏览器初次接收到 401 会弹出认证用的对话窗口
403:表示请求资源的访问被服务器拒绝了,服务器如果想给出拒绝的理由可以在主体内容中对原因进行描述。404:表示服务器上无法找到请求的资源,可以用在服务器拒绝请求又不想说明理由的场合
405:表示服务器不支持使用该请求方法请求指定资源
412:表示客户端附带条件的请求与资源的实体标记不匹配,服务器将不会执行请求
415:表示请求传给服务器端的实体内容并不是服务器端所支持的媒体类型
417:一般发生在客户端带有 Expect 请求头的时候期望服务器出现特定的行为而服务器无法理解时将返回 417

500:表示服务器在执行请求时发生了错误
503:表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

对于 302/303/307 的理解:
首先 303 和 307 是 http1.1 规范的产物, 在 http1.0 的时候只有 302 的状态码, 规范规定: 客户端发出的请求服务器返回 302 的状态码, 如果请求是 post, 禁止在用户未允许的情况下再次发送请求, 因为 post 请求是非幂等的, 下次请求的环境可能已经发生了变化。而广大浏览器均没有遵守此规范, 都是收到 302 的状态码后将请求改为 get 再次请求响应的 Location 里的 URI。
由于规范中的 302 浏览器均为遵守, 于是在 http1.1 的规范中新提出 303 和 307 的状态码。浏览器目前行为就实现了 303 的规范, 如果收到 303 的状态码就将请求改为 get 再次请求 Location 里的 URI
307 则指出需要在响应实体中包含信息,以便不能处理 307 状态码的用户有能力在新 URI 中发起重复请求,也就是说,把重定向的页面展示给用户,让用户去点重定向 URI 链接

个人认为在 http1.1 中, 理论上来说 302 应该是被废弃的, 因为 307 和 302 的说法并无二意, 可能是为了兼容 302 还在业界的大量使用吧

11.HTTP1.1 规范允许利用虚拟主机(virtual host)的功能在同一台 HTTP 服务器上搭建多个 Web 站点。若相同的域名部署在同一台服务器上,使用 DNS 服务解析域名后会得到相同的 IP 地址,所以在
发送 HTTP 请求时必须在 Host 首部内完整指定主机名和域名 URI。

12. 用于通信数据转发的应用程序,如代理、网关、隧道
1) 代理:一种具有转发功能的应用程序,扮演位于服务器和客户端之间的“中间人”的角色,可以将客户端的请求转发给服务器,也可以将服务器的响应转发给客户端。使用代理的场景:减少网络带宽、针对特定网站的访问控制。
a. 缓存代理(利用缓存技术减少网络带宽流量),预先将资源的副本缓存在代理服务器上
b. 透明代理(不对请求报文或响应报文做任何处理)
c. 非透明代理
2) 网关:转发其他服务器通信数据的服务器(工作机制与代理十分相似),它就像自己拥有资源的服务器(源服务器:拥有实体资源的的服务器),可以对客户端发送来的请求进行处理。
a. 通过网关将 HTTP 协议的请求转化为非 HTTP 协议的通信
b. 提高通信的安全性
3) 隧道:一种在相距甚远的客户端和服务器端之间进行中转(透明传输,并不会解析 HTTP 请求),并保持双方通信连接的应用程序。通过时会使用 SSL 加密手段进行通信

13.HTTP 报文首部:报文首部字段有字段名和字段值的结构组成中间用 ”:” 分隔,字段值对应于单个首部可以有多个值,如 2:
1)Content-Type: text/html 表示报文主体的对象类型,
2)Keep-Alive: timeoue=15, max=100

14.HTTP 报文通用首部相关字段说明

1)Cache-Control
    a. 作为请求时的字段
    no-cache: 强制向服务器再次验证,为了防止缓存中返回过期的资源,其实此字段表示不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,使用缓存则需要经过协商缓存来验证决定
    no-store: 暗示请求和响应中包含机密信息,规定不能在本地缓存请求或响应中的任一部分
    max-age: 值的单位为秒,资源的缓存时间比指定时间小的时候,客户端将接收缓存的资源,如果其值为 0 时表示缓存服务器需要将请求转发给源服务器
    min-fresh: 值的单位为秒,要求缓存服务器返回至少还未过指定改时间的缓存资源,如其指定为 60s,过了 60s 的缓存资源将不会作为响应返回了
    max-stale: 单位为秒,只可接收缓存资源,即使是过期但未超过其指定的时间值的资源也接收
    only-if-cached: 表示客户端仅在缓存服务器在本地缓存了目标资源的情况下才会要求其返回,也就是说缓存服务器不重新加载响应,也不再次确认资源的有效性
    must-revalidate: 缓存服务器会再次向源服务器请求即将返回的缓存资源是否有效,若缓存服务器无法连通源服务器获取资源则将返回给客户端 504 的状态码,会忽略 max-stale 字段
    proxy-revalidate: 表示缓存服务器在向客户端返回响应前必须再次验证资源缓存的有效性
    no-transfrom: 规定无论在请求还是响应中,缓存都不能改变主题的媒体类型,可防止缓存或代理压缩图片等类的操作
    #cache-extension: 用来扩展 Cache-Control 首部字段内的字段名,如果缓存服务器不能理解扩展的字段则会忽略,如扩展一个 community 字段:Cache-Control: community="UCT"

    b. 作为响应时的字段
    no-cache: 表示缓存服务器不能对资源进行缓存
    no-store: 暗示请求和响应中包含机密信息,规定不能在本地缓存请求或响应中的任一部分
    max-age: 响应首部中包含 max-age 字段时缓存服务器将不再对资源的有效性进行确认,其值表示资缓存的最长时间

2)Connection 有两个作用:控制不再转发给代理的首部字段、管理持久连接
    客户端请求时或服务端返回响应时,使用 Connection 首部字段可控制不再转发给代理的首部字段,如 Connection: Upgrade 表示删掉 Upgrade 这个字段
    HTTP/1.1 版本的默认连接都是持久连接,当某一段明确想要断开连接时,则指定 Connection 的值为 close

3)Date 表示创建 HTTP 报文的日期和时间

4)Pragma:作为 HTTP/1.0 向后兼容的字段,也属于通用首部字段,只用在客户端发送的请求中,表示客户端要求中间服务器不返回缓存的资源

5)Warning:告知用户一些与缓存相关的问题的警告,其格式为:Warning: [警告码][警告的主机: 端口][警告内容]([日期时间])

15. 请求首部相关字段:用于补充请求的附加信息、客户端信息、对响应内容相关的优先级

1)Accept: 通知服务器用户代理可处理的媒体类型及媒体类型的优先级。可以用 type/subtype 这种格式的的形式,如文本类型 Accept: text/html, text/plain; q = 0.8 ...
2)Accept-Charset: 通知服务器用户代理可处理的字符集及字符集的优先级。3)Accept-Encoding: 通知服务器用户代理可处理的内容集及内容编码的优先级。如:Accept-Encoding: gzip, deflate  另外,也可以指定“*”表示通配符,指定任意的编码格式
4)Accept-Language: 通知服务器用户代理可处理的自然语言集及自然语言集的优先级。如:Accept-Language: zh-cn, zh;q=0.8, en-us, en;q=0.6
5)Authorization: 告知服务器用户代理的认证信息
6)Expect: 使用此字段告诉服务器期望出现某种特定的行为,如果服务器不能理解客户端期望则回应发生错误时返回 417 的状态码
7)From: 使用此头部告诉服务器正在使用用户代理的这位用户的电子邮箱地址,有时候因为用户代理的不同,会将此字段放在 User-Agent 中
8)Host: 此字段告知服务器请求资源所在的互联网的主机名和端口号,这是 HTTP/1.1 规范中唯一一个必须包含在请求内的首部字段。这是因为有可能很多域名部署在同一台服务器上的不同
虚拟机中,在请求发至服务器中,请求中的主机名会用 IP 代替,如果这时此 IP 下部署着多个域名,那么服务器就无法理解究竟是哪个域名对应的请求,这时 Host 就显得很有用了,如果服务器的未设定主机名,则传一个空值即可。9)If-Match: 形如 If-XXX 这种的请求都可称为条件请求,服务器接收到这种请求后,只有判断条件为真,才会执行请求。若附带条件与资源的实体标记不匹配时 会返回 412 precondition failed 的状态码。若此字段的值为 "*",服务器将会忽略 ETag 的值,只要资源存在就执行请求
10)If-Modified-Since: 若服务器的资源在此字段指定的时间之后更新了,服务器会执行请求,否则会返回 304 Not Modified 的状态码。如果要获取资源的更新时间则确认响应头中的 Last Modified 字段可获取。浏览器在第一次访问资源时,服务器返回资源的同时,在 response header 中添加 Last-Modified 的 header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和 header。浏览器下一次请求这个资源,浏览器检测到有 Last-Modified 这个 header,于是在请求时添加 If-Modified-Since 这个 header,值就是 Last-Modified 中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回 304 和空的响应体,直接从缓存读取,如果 If-Modified-Since 的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和 200
11)If-None-Match: 表示此字段与请求资源的实体标记(ETag)不一致时希望处理请求,这与 If-Match 相反。在 GET 与 HEAD 请求中,使用此字段可获取最新的资源。使用此字段可获取最新资源的原理如下:在第一次请求时服务器响应中添加 ETag 信息,客户端将 ETag 值存储,再次发送请求时将 ETag 值发送给服务器,服务器验证 ETag 是否改变,若改变则说明资源已经更新,则会处理请求,否则就返回 304 状态码
12)If-Range: 告知服务器如果此字段的值和请求资源的 ETag 值一致时就返回范围请求,不一致就返回全体资源。若不使用 If-Range,如果服务器端资源更新字 ETag 值也将发生变化,则客户端
已持有的一部分资源将无效,此时服务器将返回 412 的状态码,而导致客户端再次请求,这样便花费了两倍的时间。13)If-Unmodified-Since: 与 If-Modified-Since 字段相反,告知服务器如果资源在此时间点之后未发生更新才处理请求,否则返回 412 状态码
14)Max-Forwards: 表示可通过的代理服务器个数,请求每经过一个代理服务器此值就减 1,直到代理服务器收到后此值为 0 时就不再做转发处理而是直接返回响应。利用此字段可以调试某台代理服务器是否出现了故障
15)Proxy-Authorization: 客户端接收到代理服务器发来的认证质询时,将会发送包含此字段的请求,以告知服务器认证的信息。这与带 Authorization 字段的认证很类似,只不过此认证行为
发生这是发生在客户端和代理之间
16)Range: 对于获取资源的部分请求往往会附带这样的请求头,如:Range: bytes=5001-10000 表示获取资源第 5001 字节至 10000 字节之间的范围,若处理请求返回后将返回 206 的状态码,若
无法处理请求将返回 200 的状态码及全部资源
17)Referer: 告知服务器是从哪个页面链接过来的
18)Te: 告知服务器客户端能够处理的传输编码方式以及相对优先性,此字段与 Accept-Encoding 很像,但此字段是用于传输编码的
19)User-Agent: 将用户代理的字符串等信息传达给服务器

16. 响应首部相关字段:补充响应的附加信息、服务器信息等,以及对客户端的附加要求等

1)Accepts-Range: 告知客户端服务器能否处理范围请求,值为 bytes 和 none 之间可选
2)Age: 告知客户端源服务器在多久前创建了响应,字段值的单位秒。若该字段由缓存服务器创建,则 Age 值表示缓存后的响应再次发起认证到认证完成的时间值
3)ETag: 告知客户端请求的资源的实体标识,服务器会为每份资源分配对应的 ETag 值,另外,当资源更新时,对应的 ETag 值也将随之更新
强 ETag:无论实体发生多么细微的变化,ETag 值都将发生变化
弱 ETag:只用于提示资源是否相同,有资源发生了根本变化,产生了差异时 ETag 才会随之变化,这是会在字段最开始附加 W /
4)Location: 使用此字段可将响应接收方引导至某个与请求 URI 位置不同的资源,可配合 3XX 的状态码提供重定向的 URI,几乎所有浏览器在接收到包含 Location 字段的响应后都将强制性第尝试对以提示的重定向资源进行访问
5)Proxy-Authenticate: 此字段把代理服务器所要求的认证信息发送给客户端,此认证发生在客户端与代理服务器之间。6)Retry-After: 告知客户端应在多久后再次发送请求,一般可配合状态码 503 一起使用。可指定确定的时间或者在此时间(单位为秒)之后再发送请求。7)Server: 当前服务器上安装的 HTTP 服务器应用程序的信息,这不单单会标出应用软件的名称,还可能包含版本号和安装时启用的可选项
8)Vary: 用在客户端或者缓存服务器上缓存机制做缓存的时候,此字段的内容来自于请求头中的相关信息,如:Vary: Accept-Encoding, User-Agent。在缓存服务器中,对首次请求到的响应做了缓存,当下次有请求过来时,缓存浏览器将会 Accept-Encoding、User-Agent 两个请求头的的内容个作为判断是否应该返回缓存数据,当同一请求的缓存数据中的 Accept-Encoding 和
User-Agent 与请求头中的 Accept-Encoding 和 User-Agent 内容相匹配时就返回缓存
9)WWW-Authenticate: 

17. 实体首部报文:包含在请求报文和响应报文中的实体部分所使用的首部,用于补充实体内容的更新等于实体相关的信息

1)Allow: 通知客户端指定资源支持的 HTTP 请求的所有方法,如果客户端使用了不允许的请求方法会返回 405 Method Not Allowed 的状态码
2)Content-Encoding: 告知客户端服务器对实体的主体内容选用的内容编码方式。此内容编码是指在不丢失实体信息的前提下所进行的压缩
3)Content-Language: 实体主体内容使用的自然语言
4)Content-Length: 表示实体主体部分的大小,单位为字节。如果对实体进行了编码,则不会使用 Content-Length 字段
5)Content-Location: 表示报文主体相对应的 URI,此字段以 Location 不同,Location 表示重定向请求的目的地址(或者新创建的文件的 URL),其对应的是响应,而 Content-Location 对应的是要返回的实体内容部分
6)Content-MD5: 服务器端将报文主体经过 MD5 算法再使用 base64 编码后传输给客户端,客户端通过同样的方法处理后与此字段的值进行对比来判断报文是否准确。此方法不能判断报文主体是否被恶意篡改,因为报文主体被篡改的话,Content-MD5 的值也将会被改变
7)Content-Range: 针对范围请求返回的响应,值表示当前发送的部分其整个实体的大小,单位为字节
8)Content-Type: 和首部字段 Accept 一样,说明主体内容的媒体类型
9)Expires: 告知客户端资源失效的日期和时间。当首部字段含有 Cache-Control 指定的 max-age 时会优先处理 max-age 指令
10)Last-Modified: 资源上一次的修改时间

18.Cookie:

1)Set-Cookie: 响应首部字段,当服务器准备开始管理客户端的状态时,会实现告诉各种信息,一下说明此首部各字段的含义
    NAME=VALUE: 赋予 Cookie 的名称和值
    expires=DATE: Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止)path=PATH: 指定 ceCookie 在那些路径下可以使用,仅在子路径可使用(不指定则默认指定为文档所在的文件目录)domain=domain: 指定 Cookie 在哪个域名下可以使用(若不指定则默认为服务器所在的域名)Secure: 仅在 HTTPS 协议下才会回收 Cookie
    HttpOnly: 加以限制,使 Cookie 不能被客户端 JavaScript 脚本访问
2)Cookie: 将接收到的 Cookie 返回给服务器端

19. 其他首部字段:HTTP 首部字段时可以扩展的。

1)X-Frame-Options: 属于响应首部,控制此网站的其他 Web 站点的 frame 标签内的显示问题,防止点击劫持攻击。DENY: 拒绝
    SAMEORIGIN: 仅在同源域名下的页面匹配是允许加载
2)X-XSS-Protection: 属于响应首部,针对跨站脚本的攻击对策,用于控制浏览器 XSS 防护机制的开关
    0: 将 XSS 过滤设置为无效状态
    1: 将 XSS 过滤设置为有效状态
3)DNT: 属于请求首部,(Do Not Track),拒绝个人信息被收集,这是拒绝被精准广告追踪的一种方法。需要 Web 服务器对 DNT 做支持
    0: 同意被追踪
    1: 拒绝被追踪
4)P3P: 属于响应首部,将 Web 程序上的个人信息变成一种仅供程序可理解的形式

文中若有表述不妥或是知识点有误之处,欢迎留言指正批评!

正文完
 0