Skip to content

Latest commit

 

History

History
735 lines (430 loc) · 47.6 KB

图解http学习笔记.md

File metadata and controls

735 lines (430 loc) · 47.6 KB

图解HTTP学习笔记

1. TCP/IP协议族

1.1 TCP/IP的分层管理

  • 应用层:应用层决定了向用户提供应用服务时通信的活动。TCP/IP协议族内预存了各类通用的应用服务。如:FTP、DNS、HTTP等。

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

    传输层中的两种不同的协议:

    • TCP:传输控制协议
    • UDP:用户数据报协议
  • 网络层:网络层用来处理在网络上流动的数据包,该层规定了通过怎样的传输路径将数据包传送到对方的计算机。

  • 数据链路层:用来处理连接网络的硬件部分。包括操作系统、硬件设备驱动、网卡、光钎等硬件。

1.2 TCP/IP通信传输流

利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则往应用层上走。

发送端:应用层→传输层→网络层→链路层
接收端:链路层→网络层→传输层→应用层

发送端在层与层之间传输时,每经过一层时必定会被打上一个该层所属的首部信息。接收端在层与层传输数据时,每经过一层时会把对应的首部信息消去。这种把数据信息包装起来的做法称为封装。

1.3 IP、TCP和DNS

1.3.1 IP协议

IP协议位于网络层,作用是把各种数据包传送给对方。IP协议要想将数据包准确的传输到对方的电脑,需要的两个重要的条件就是IP地址和MAC地址。并使用ARP协议(根据IP地址获取物理地址的一个TCP/IP协议)凭借MAC地址进行通信。

IP地址和MAC地址:

  • IP地址:指明了节点被分配到的地址
  • MAC地址:网卡的固定物理地址,大部分的时候不会改变(可通过工具来修改)

在到达通信目标的中转过程中,计算机和路由器等网络设备只能熟悉很粗略的传输路线,这种机制叫做路由选择。

1.4 确保可靠性的TCP协议

TCP协议位于传输层,提供可靠的字节流服务。字节流服务是指,为了方便传输,将大块数据分割以报分段为单位的数据进行管理。TCP协议使用三次握手策略保证数据准确无误的到达目标处。

TCP三次握手策略:

为了准确无误的将数据送到对方,TCP协议在传输数据后会向对方确认是否送达。握手的过程中使用了TCP的标志——SYN(同步标志)和ACK(确认标志)。

三次握手过程(来自维基百科):

TCP用三路握手(或称三次握手,three-way handshake)过程创建一个连接。在连接创建过程中,很多参数要被初始化,例如序号被初始化以保证按序传输和连接的强壮性。
一对终端同时初始化一个它们之间的连接是可能的。但通常是由一端打开一个套接字(socket)然后监听来自另一方的连接,这就是通常所指的被动打开(passive open)。服务器端被被动打开以后,用户端就能开始创建主动打开(active open)。

  1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数A。
  2. 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK的确认码应为A+1,SYN/ACK包本身又有一个随机产生的序号B。
  3. 最后,客户端再发送一个ACK。当服务端收到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包的序号被设定为收到的确认号A+1,而响应号则为B+1。

如果服务器端接到了客户端发的SYN后回了SYN-ACK后客户端掉线了,服务器端没有收到客户端回来的ACK,那么,这个连接处于一个中间状态,即没成功,也没失败。于是,服务器端如果在一定时间内没有收到的TCP会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s才知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才会断开这个连接。使用三个TCP参数来调整行为:tcp_synack_retries 减少重试次数;tcp_max_syn_backlog,增大SYN连接数;tcp_abort_on_overflow决定超出能力时的行为。

1.5 DNS域名解析服务

和HTTP一样,DNS服务也处于应用层。它提供域名到IP地址间的解析服务。由于IP不方便用户记忆。所以用户通常使用域名或者主机名来访问对方的计算机。DNS协议存在的目的就是通过域名查找对方计算机的IP地址,或逆向从IP地址反查域名服务。

DNS系统中,常见的资源记录类型有(来自维基百科):

  • 主机记录(A记录):RFC 1035定义,A记录是用于名称解析的重要记录,它将特定的主机名映射到对应主机的IP地址上。
  • 别名记录(CNAME记录): RFC 1035定义,CNAME记录用于将某个别名指向到某个A记录上,这样就不需要再为某个新名字另外创建一条新的A记录。
  • IPv6主机记录(AAAA记录): RFC 3596定义,与A记录对应,用于将特定的主机名映射到一个主机的IPv6地址。
  • 服务位置记录(SRV记录): RFC 2782定义,用于定义提供特定服务的服务器的位置,如主机(hostname),端口(port number)等。
  • NAPTR记录:RFC 3403定义,它提供了正则表达式方式去映射一个域名。NAPTR记录非常著名的一个应用是用于ENUM查询。

1.6 一个完整的HTTP通信中,IP、TCP、DNS的作用

当我们打开一个网站,如 http://www.github.com

  • DNS服务的职责:客户端通过DNS解析服务器(或本地DNS缓存),解析出github对应的IP地址。
  • HTTP协议的职责:发送方,生成对目标web服务器的http请求报文。接收方:对web服务器请求的内容进行处理。
  • TCP协议的职责:在发送方,为了方便通信,将HTTP请求报文分给成报文段,并传送给对方。在接收方,按照序号,将对方传送过来的报文段进行重组。
  • IP协议的职责:搜索对方的地址,一边中专一边传送。

1.7 URI、URL、URN

内容来自维基百科

  • URI:统一资源标识符
    统一资源标识符(英语:Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对网络中(一般指万维网)的资源通过特定的协议进行交互操作。URI的最常见的形式是统一资源定位符(URL),经常指定为非正式的网址。更罕见的用法是统一资源名称(URN),其目的是通过提供一种途径。用于在特定的名字空间资源的标识,以补充网址。

  • URL:统一资源定位符
    统一资源定位符(或称统一资源定位器/定位地址、URL地址等[1],英语:Uniform Resource Locator,常缩写为URL),有时也被俗称为网页地址(网址)。如同在网络上的门牌,是因特网上标准的资源的地址(Address)

  • URN:统一资源名称
    统一资源名称(英语:Uniform Resource Name,或URN)是统一资源标识(URI)的历史名字

1.7.1 URI与URL和URN的关系

URL(定位符)和URN(名称)方案属于URI的子类,URI可以为URL或URN两者之一或同时是URI和URN。技术上讲,URL和URN属于资源ID;但是,人们往往无法将某种方案归类于两者中的某一个:所有的URI都可被作为名称看待,而某些方案同时体现了两者中的不同部分。

URI可被视为定位符(URL),名称(URN)或两者兼备。统一资源名(URN)如同一个人的名称,而统一资源定位符(URL)代表一个人的住址。换言之,URN定义某事物的身份,而URL提供查找该事物的方法。

1.7.2 URI格式

URI文法由URI协议名(例如“http”,“ftp”,“mailto”或“file”),一个冒号,和协议对应的内容所构成。特定的协议定义了协议内容的语法和语义,而所有的协议都必须遵循一定的URI文法通用规则,亦即为某些专门目的保留部分特殊字符。URI文法同时也就各种原因对协议内容加以其他的限制,例如,保证各种分层协议之间的协同性。百分号编码也为URI提供附加信息。

通用URI的格式如下:

 scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]

2. HTTP协议

超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。

2.1 HTTP方法

方法名称 说明 支持的HTTP协议版本
GET 用来请求已被URI识别的资源 1.0、1.1
POST 传输实体的主体 1.0、1.1
PUT 传输文件 1.0、1.1
HEAD 获得报文首部。HEAD方法和GET方法类似,只是不返回报文的主体部分。用于确认URI的有效性和资源更新的时间等。 1.0、1.1
DELETE 删除文件,与PUT方法相反 1.0、1.1
OPTIONS 用来查询针对请求URI指定的资源支持的方法 1.1
TRACE 让WEB服务器端将之前的请求通信环回给客户端的方法。不常用,并且容易引发XST攻击。 1.1
CONNECT 要求使用隧道协议链接代理,与服务器通信时建立隧道,实现用隧道协议进行TCP通信。 1.1
LINK 建立和资源之间的联系 1.0
UNLINK 断开连接关系 1.0

2.2 持久连接

内容来自维基百科

HTTP持久连接(HTTP persistent connection,也称作HTTP keep-alive或HTTP connection reuse)是使用同一个TCP连接来发送和接收多个HTTP请求/应答,而不是为每一个新的请求/应答打开新的连接的方法。

在 HTTP 1.1 中 所有的连接默认都是持续连接,除非特殊声明不支持。HTTP 持久连接不使用独立的 keepalive 信息,而是仅仅允许多个请求使用单个连接。然而, Apache 2.0 httpd 的默认连接过期时间是仅仅15秒,对于 Apache 2.2 只有5秒。短的过期时间的优点是能够快速的传输多个web页组件,而不会绑定多个服务器进程或线程太长时间。

优点:

  • 较少的CPU和内存的使用(由于同时打开的连接的减少了)
  • 允许请求和应答的HTTP管线化
  • 降低拥塞控制 (TCP连接减少了)
  • 减少了后续请求的延迟(无需再进行握手)
  • 报告错误无需关闭TCP连接

缺点:

对于现在的广泛普及的宽带连接来说,Keep-Alive也许并不像以前一样有用。web服务器会保持连接若干秒(Apache中默认15秒),这与提高的性能相比也许会影响性能。

对于单个文件被不断请求的服务(例如图片存放网站),Keep-Alive可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间。

2.3 管线化

HTTP管线化是将多个HTTP请求整批提交的技术,而在发送过程中不需先等待服务端的回应。持久连接使得多数请求以管线化的方式发送成为可能,这样就能同时并行发送多个请求,而不需要一个接一个的等待响应。

2.4 使用Cookie进行状态管理

HTTP时无状态协议,它不对之前发生过的请求状态进行管理,无法根据之前的状态进行本次的请求处理。为了解决这个问题,引入了Cookie技术进行状态管理。

Cookie的使用原理:

  • Cookie通过在请求和响应的报文中写入Cookie信息来控制客户端状态。
  • Cookie会根据从服务端发送的响应报文内的一个叫做Set-Cookie的首部段信息,通知客户端保存Cookie。当下次客户端再发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务端发现客户端发送的Cookie后,会去检查其属于哪个客户端,然后对比服务器上的记录,得到之前的状态信息。

Cookie的缺陷:

  • Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
  • 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用- HTTPS。
  • Cookie的大小限制在4KB左右,对于复杂的存储需求来说是不够用的。

2.5 HTTP版本

内容来自维基百科

超文本传输协议已经演化出了很多版本,它们中的大部分都是向下兼容的。在 RFC 2145 中描述了HTTP版本号的用法。客户端在请求的开始告诉服务器它采用的协议版本号,而后者则在响应中采用相同或者更早的协议版本。

  • HTTP/0.9
    已过时。只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息。

  • HTTP/1.0
    这是第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用,特别是在代理服务器中。

  • HTTP/1.1
    持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求,以便降低线路负载,提高传输速度。

  • HTTP/2
    当前版本,于2015年5月作为互联网标准正式发布。

HTTP/1.1相较于HTTP/1.0协议的区别主要体现在:

  • 缓存处理
  • 带宽优化及网络连接的使用
  • 错误通知的管理
  • 消息在网络中的发送
  • 互联网地址的维护
  • 安全性及完整性

HTTP/2与HTTP/1.1比较:
HTTP/2 相比 HTTP/1.1 的修改并不会破坏现有程序的工作,但是新的程序可以借由新特性得到更好的速度。

HTTP/2 保留了 HTTP/1.1 的大部分语义,例如请求方法、状态码乃至URI和绝大多数HTTP头部字段一致。而 HTTP/2 采用了新的方法来编码、传输客户端——服务器间的数据。

3. HTTP报文

3.1 认识HTTP报文

什么是HTTP报文?
用于HTTP协议交互的信息被称为HTTP报文。请求端的HTTP报文叫做请求报文,响应端的叫做响应报文。

3.2 HTTP报文结构

请求/响应报文由以下内容组成:

结构 说明
报文首部 服务器端或客户端处理的请求或响应的内容以及属性
空行(CR+LF) CR(回车符:16进制的0x0d)和LF(换行符:16进制0x0a)
报文主体 应被发送的数据

报文首部的组成:

  • 请求行,例如:GET /logo.gif HTTP/1.1或状态码行,例如:HTTP/1.1 200 OK,

  • 首部字段:包含表示请求的各种条件和属性的各类首部。 一般有4种首部:通用首部、请求首部、响应首部、实体首部

  • 其他:可能包含HTTP的RFC里未定义的首部(Cookie等)。

3.3 HTTP编码提升传输速率

在HTTP的传输过程中,可以通过编码提升传输速率。通过在传输时编码,能有效的处理大量的访问请求。HTTP压缩是一种内置到网页服务器和网页客户端中以改进传输速度和带宽利用率的方式。

3.3.1 报文主体和实体主体的差异:

  • 报文:是HTTP通信中的基本单位,由8位字节流组成,通过HTTP通信传输。

  • 实体:作为请求或响应的有效载荷数据被传输,其内容由实体首部和实体主体组成。

  • 差异:通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体内容发生变化,才导致它和报文主体产生差异。

3.3.2 压缩传输内容的编码

压缩的实现:

在HTTP中有两种不同的方式可以完成压缩。在较低层级,Transfer-Encoding头可以指示HTTP消息的有效载荷被压缩。在较高层级,Content-Encoding头可以指示一个被转码、缓存或引用的资源已压缩。使用Content-Encoding的压缩比Transfer-Encoding有更广泛的支持,并且某些浏览器不宣告Transfer-Encoding压缩以避免触发服务器的缺陷。

压缩方案的协商:

内容来自维基百科

在大多数情况中(不包括SDCH),协商使用两个步骤完成,这描述在RFC 2616:

  1. 网页客户端在HTTP请求的头部通告其支持的压缩方案为一个标记列表(tokens)。对于Content-Encoding,这个列表称作Accept-Encoding;对于Transfer-Encoding,该字段被称为TE。
GET /encrypted-area HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, deflate

  1. 如果服务器支持一种或多种压缩方案,输出的数据可能用一种或多种双方支持的方法压缩。如果是这种情况,服务器将在HTTP响应中添加一个Content-Encoding或Transfer-Encoding字段表明使用的方案,用逗号分隔。
HTTP/1.1 200 OK
Date: Tue, 27 Feb 2018 06:03:16 GMT
Server: Apache/1.3.3.7 (Unix)  (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Accept-Ranges: bytes
Content-Length: 438
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip

常见的几种内容编码(Content-Encoding标记):

  • gzip GNU zip格式(定义于RFC 1952)。此方法截至2011年3月,是应用程序支持最广泛的方法。
  • compress (UNIX系统的标准压缩)UNIX的“compress”程序的方法(历史性,不推荐大多数应用使用,应该使用gzip或deflate)
  • deflate(zlib)基于deflate算法(定义于RFC 1951)的压缩,使用zlib数据格式(RFC 1950)封装
  • identity(不进行编码)这是内容编码的默认值。
  • br Brotli,一种新的开源压缩算法,专为HTTP内容的编码而设计,已在Mozilla Firefox 44中实现,并且Chromium正准备实施

3.4 发送多种数据的多部分对象集合

发送的一份报文主体内可含有多类型实体。通常在图片或者文本上传时使用。在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-type。

多部分对象集合包含的对象:

  • multipart/form-data : 在web表单文件上传时使用。

  • multipart/byteranges :状态码206响应报文包含了多个范围的内容使用。

3.5 获取部分内容的范围请求

执行范围请求时,会用到首部字段Range来制定资源的byte范围。针对范围请求,响应会返回状态码206的响应报文。并且会在首部字段Content-Type表明multipart/byteranges后返回响应报文。若服务端无法响应范围请求,则会返回状态码200 OK和完整的实体内容。

byte范围的指定形式如下:

  • Range:bytes=5001-10000 获取5001-10000字节

  • Range:bytes=5001- 获取5001后全部的

  • Range:bytes=-5001,6000-7000 从一开始到5001字节和6000-7000字节的多重范围

3.6 内容协商返回最合适的内容

内容协商机制是指客户端和服务端就响应的资源进行交涉,然后提供给客户端最为合适的资源。

内容协商判断首部字段:

  • Accept

  • Accept-Charset

  • Accept-Encoding

  • Accept-Language

  • Content-Language

内容协商技术:

  • 服务器驱动协商:由服务器进行内容协商,以请求首部字段为参考,在服务器自动处理。

  • 客户端驱动协商:用户在浏览器页面中手动选择。

  • 透明协商:是服务器和客户端驱动的结合体,是有服务器端和客户端各自进行内容协商的一种方法。

4. HTTP状态码

部分内容来自维基百科 HTTP状态码

HTTP状态码(英语:HTTP Status Code)是用以表示网页服务器超文本传输协议响应状态的3位数字代码。状态码的职责是当客户端向服务器发送请求时,描述返回的请求结果。用户能够通过返回的状态码判断请求结果。状态码以三位数字和原因短语组成,数字第一位指定响应类别,后两位无分类。

1XX

information(信息状态码),表示接收的请求正在处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于HTTP/1.0协议中没有定义任何1xx状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送1xx响应。这些状态码代表的响应都是信息性的,标示客户应该采取的其他行动。

  • 100 Continue

    服务器已经接收到请求头,并且客户端应继续发送请求主体(在需要发送身体的请求的情况下:例如,POST请求),或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。要使服务器检查请求的头部,客户端必须在其初始请求中发送Expect: 100-continue作为头部,并在发送正文之前接收100 Continue状态代码。响应代码417期望失败表示请求不应继续。

  • 101 Switching Protocols

    服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在Upgrade消息头中定义的那些协议。
    只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP版本(如HTTP/2)比旧版本更有优势,或者切换到一个实时且同步的协议(如WebSocket)以传送利用此类特性的资源。

  • 102 Processing(WebDAV;RFC 2518)

    WebDAV请求可能包含许多涉及文件操作的子请求,需要很长时间才能完成请求。该代码表示​​服务器已经收到并正在处理请求,但无响应可用。[6]这样可以防止客户端超时,并假设请求丢失。

2XX 成功

Success(成功状态码),表示请求正常处理完毕。

  • 200 OK

    表示从客户端发来的请求在服务器被正常处理了

  • 204 No Content

    表示请求被成功处理,但是没有响应实体的主体部分。

  • 206 Partial Content

    范围请求,响应报文中包含由Content-Range制定范围的实体内容。

3XX 重定向

Redirection(重定向),需要进行附加操作以完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。当且仅当后续的请求所使用的方法是GET或者HEAD时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。客户端应当自动监测无限循环重定向(例如:A→B→C→……→A或A→A),因为这会导致服务器和客户端大量不必要的资源消耗。按照HTTP/1.0版规范的建议,浏览器不应自动访问超过5次的重定向。

  • 300 Multiple Choices

    被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。 除非这是一个HEAD请求,否则该响应应当包括一个资源特性及地址的列表的实体,以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由Content-Type定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力,自动作出最合适的选择。当然,RFC 2616规范并没有规定这样的自动选择该如何进行。 如果服务器本身已经有了首选的回馈选择,那么在Location中应当指明这个回馈的URI;浏览器可能会将这个Location值作为自动重定向的地址。此外,除非额外指定,否则这个响应也是可缓存的。

  • 301 Moved Permanently

    被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。 新的永久性的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。 如果这不是一个GET或者HEAD请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。 注意:对于某些使用HTTP/1.0协议的浏览器,当它们发送的POST请求得到了一个301响应的话,接下来的重定向请求将会变成GET方式。

  • 302 Found

    要求客户端执行临时重定向(原始描述短语为“Moved Temporarily”)。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。 新的临时性的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。 如果这不是一个GET或者HEAD请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。 注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用GET方式访问在Location中规定的URI,而无视原先请求的方法。因此状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。

  • 303 See Other

    对应当前请求的响应可以在另一个URI上被找到,当响应于POST(或PUT / DELETE)接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的GET消息发出重定向。[23]这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的URI不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。 新的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。 注意:许多HTTP/1.1版以前的浏览器不能正确理解303状态。如果需要考虑与这些浏览器之间的互动,302状态码应该可以胜任,因为大多数的浏览器处理302响应时的方式恰恰就是上述规范要求客户端处理303响应时应当做的。

  • 304 Not Modified

    表示资源未被修改,因为请求头指定的版本If-Modified-Since或If-None-Match。在这种情况下,由于客户端仍然具有以前下载的副本,因此不需要重新传输资源。

  • 305 Use Proxy

    被请求的资源必须通过指定的代理才能被访问。Location域中将给出指定的代理所在的URI信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能创建305响应。许多HTTP客户端(像是Mozilla[25]和Internet Explorer)都没有正确处理这种状态代码的响应,主要是出于安全考虑。 注意:RFC 2068中没有明确305响应是为了重定向一个单独的请求,而且只能被原始服务器建立。忽视这些限制可能导致严重的安全后果。

  • 306 Switch Proxy

    在最新版的规范中,306状态码已经不再被使用。最初是指“后续请求应使用指定的代理”。

  • 307 Temporary Redirect

    在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI。 与302相反,当重新发出原始请求时,不允许更改请求方法。 例如,应该使用另一个POST请求来重复POST请求。

  • 308 Permanent Redirect (RFC 7538)

    请求和所有将来的请求应该使用另一个URI重复。 307和308重复302和301的行为,但不允许HTTP方法更改。 例如,将表单提交给永久重定向的资源可能会顺利进行。

4xx 客户端错误

这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。

如果错误发生时客户端正在传送数据,那么使用TCP的服务器实现应当仔细确保在关闭客户端与服务器之间的连接之前,客户端已经收到了包含错误信息的数据包。如果客户端在收到错误信息后继续向服务器发送数据,服务器的TCP栈将向客户端发送一个重置数据包,以清除该客户端所有还未识别的输入缓冲,以免这些数据被服务器上的应用程序读取并干扰后者。

  • 400 Bad Request

    报文中存在语法错误,服务器无法理解。

  • 401 Unauthorized

    表示请求需要有通过HTTP认证的认证信息。若之前已经认证过,则表示认证失败。

  • 403 Forbidden

    请求资源被拒绝。可以简单的理解为没有权限访问此站,服务器收到请求但拒绝提供服务。如:文件系统访问权限问题

  • 404 Not Found

    请求失败,请求所希望得到的资源未被在服务器上发现,但允许用户的后续请求。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。

  • 408 Request Timeout

    请求超时。根据HTTP规范,客户端没有在服务器预备等待的时间内完成一个请求的发送,客户端可以随时再次提交这一请求而无需进行任何更改。

5xx 服务器错误

表示服务器无法完成明显有效的请求。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。这些状态码适用于任何响应方法。

  • 500 Inter Server Error

    服务器在执行请求发生错误,也可能是web应用存在bug或临时性故障。

  • 503 Service Unavailable

    服务器超负荷或停机维护,可通过Retry-After首部返回修复时间。

5. WEB服务器

虚拟主机

虚拟主机(英语:virtual hosting)或称 共享主机(shared web hosting),又称虚拟服务器,是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术。虚拟主机之间完全独立,并可由用户自行管理,虚拟并非指不存在,而是指空间是由实体的服务器延伸而来,其硬件系统可以是基于服务器群,或者单个服务器。其技术是互联网服务器采用的节省服务器硬件成本的技术,虚拟主机技术主要应用于HTTP,FTP,EMAIL等多项服务,将一台服务器的某项或者全部服务内容逻辑划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源。如果划分是系统级别的,则称为虚拟服务器。

通信数据转发

  • 代理:代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。

    • 缓存代理:代理抓发响应时,缓存代理会预先将资源的副本保存在服务器上。当下次再请求时可以直接返回缓存资源,不必再从资源服务器获取。

    • 透明代理:转发请求或响应时,不对报文进行任何处理的代理类型称为透明代理。反之称为非透明代理。

  • 网关:网关是转发其他服务器通信数据的服务器,接收从客户端发来的请求时,它就像自己拥有资源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。

    区别于路由器(由于历史的原因,许多有关TCP/IP的文献曾经把网络层使用的路由器(英语:Router)称为网关,在今天很多局域网采用都是路由来接入网络,因此现在通常指的网关就是路由器的IP),经常在家庭中或者小型企业网络中使用,用于连接局域网和Internet。网关也经常指把一种协议转成另一种协议的设备,比如语音网关。

  • 隧道:隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。隧道的目的是确保客户端能与服务器进行安全的通信。

保存资源的缓存

缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可以减少对资源服务器的访问,因此就节省了通信流量和通信时间。

6. HTTP首部

6.1 HTTP报文首部

HTTP报文首部结构:

  • HTTP请求报文

    • 请求行

    • HTTP首部字段

      • 请求首部字段
      • 通用首部字段
      • 实体首部字段
    • 其他

  • HTTP响应报文

    • 状态行

    • HTTP首部字段

      • 响应首部字段
      • 通用首部字段
      • 实体首部字段
    • 其他

6.2 HTTP首部字段介绍

简介

HTTP首部字段(英语:HTTP header fields)是指在超文本传输协议(HTTP)的请求和响应消息中的消息头部分。它们定义了一个超文本传输协议事务中的操作参数。HTTP头部字段可以自己根据需要定义,因此可能在 Web 服务器和浏览器上发现非标准的头字段。

格式

协议头的字段,是在请求(request)或响应(response)行(一条消息的第一行内容)之后传输的。协议头的字段是以明文的字符串格式传输,是以冒号分隔的键名与键值对,以回车(CR)加换行(LF)符号序列结尾。协议头部分的结尾以一个空白字段标识,结果就是,也就是传输两个连续的CR+LF。

首部字段的组成

  • 通用首部字段:请求报文和响应报文两方都会使用的首部。

    • Cache-Control:控制缓存行为

      • 请求首部中

        字段 描述
        Cache-Control: max-age=<seconds>  设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。若值为0,缓存服务器通常需要将请求转发给源服务器。当存在该指令,缓存服务器将不再验证资源有效性,使用max-age代表资源保存为缓存的最长时间。
        Cache-Control: max-age=<seconds>  设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。若值为0,缓存服务器通常需要将请求转发给源服务器。当存在该指令,缓存服务器将不再验证资源有效性,使用max-age代表资源保存为缓存的最长时间。
        Cache-Control: max-stale=<seconds>  表明客户端愿意接收一个已经过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过时时间。该指令会忽略max-stale指令。若代理无法连通源服务器获取有效资源,缓存必须给客户端一条504(Gateway Timeout)状态码。
        Cache-Control: min-fresh=<seconds>    表示客户端希望在指定的时间内获取最新的响应。
        Cache-control: no-cache     在释放缓存副本之前,强制高速缓存将请求提交给原始服务器进行验证。\n从字面意思上很容易将no-cache误解成不缓存,但事实上no-cache代表不缓存过期的资源,缓存会向原服务器进行有效确认后处理资源。no-store才是真正的不进行缓存。
        Cache-control: no-store    缓存不应存储有关客户端请求或服务器响应的任何内容。
        Cache-control: no-transform  不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。
      • 响应首部中

        字段 描述
        Cache-control: must-revalidate    缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
        Cache-control: no-cache    在释放缓存副本之前,强制高速缓存将请求提交给原始服务器进行验证。从字面意思上很容易将no-cache误解成不缓存,但事实上no-cache代表不缓存过期的资源,缓存会向原服务器进行有效确认后处理资源。no-store才是真正的不进行缓存。
        Cache-control: no-store    缓存不应存储有关客户端请求或服务器响应的任何内容。
        Cache-control: no-transform  不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。
        Cache-control: public  表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
        Cache-control: private  表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它),可以缓存响应内容。
        Cache-control: proxy-revalidate   与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。
        Cache-Control: max-age=<seconds>    设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。若值为0,缓存服务器通常需要将请求转发给源服务器。\n当存在该指令,缓存服务器将不再验证资源有效性,使用max-age代表资源保存为缓存的最长时间。
        Cache-control: s-maxage=<seconds>   覆盖max-age 或者 Expires 头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略。
    • Connection:逐跳首部、连接的管理

    • Date:创建报文的时间

    • Pragma:HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。在HTTP/1.1中 Pragma:no cache 会被cache-control:no cache替代。

    • Trailer:报文末端的首部一览

    • Transfer-Encoding:指定报文主体的传输编码方式

    • Upgrade:用于检测HTTP协议及其他协议是否可以使用更高版本进行通信,需要配合Connection:Upgrade进行使用。

    • Via:获取报文的传输路径

    • Warning:错误通知

  • 请求首部字段:从客户端向服务端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、相应内容相关优先级信息。

    • Accept:用户代理可处理的媒体类型

    • Accept-Charset:优先的字符集

    • Accept-Encoding:优先的内容编码

    • Accept-Language:优先的语言

    • Authorization:Web的认证信息

    • Except:期待服务器的特定行为

    • From:用户的电子邮箱地址

    • Host:请求资源所在的服务器主机名。Host首部字段是在HTTP/1.1规范内唯一一个必须被包含在请求内的首部字段。

    • If-Match:比较实体标记(Etag),只有当If-Match字段和Etag字段相同时服务器才会接受请求

    • If-None-Match:比较实体标记Etag,不同时才会请求(与If-Match相反)

    • If-Modified-Since:比较资源的更新时间

    • If-Unmodified-Since:比较资源的更新时间(与If-Modified-Since相反)

    • If-Range:资源未更新时发送实体Byte的范围请求

    • Max-Forwards:最大传输逐跳数,设置可经过服务器的最大数目,服务器往下一个服务器转发请求前,会将Max-forwards的值减1后再赋值。当Max-forwards的值为0时,则不再进行转发,而是直接响应。

    • Proxy-Authorization:代理服务器要求客户端的认证信息

    • Range:实体的字节范围要求

    • Referer:请求URI的原始获取方

    • TE:传输编码优先级

    • User-Agent:HTTP客户端程序的信息

  • 响应首部字段:从服务器端向客户端返回响应报文时使用的首部。补充了响应附加内容,也会要求客户端附加额外的内容信息。

    • Accept-Ranges:用来告知客户端服务端能否处理字节范围请求,若可以则返回指定范围bytes,否则返回none。

    • Age:该首部字段能够告知客户端,源服务器在多久前创建了响应。单位:秒。

    • Etage:资源的标识字段,服务器会为每份资源分配对应的Etag值。

      • 强Etag:不论实体发生多么细微的变化都会改变其值。

      • 若Etag值:只有资源发生了根本改变,才会改变Etag值。只用于提示资源是否相同。

    • Location:令客户端重新定向至指定URI

    • Proxy-Authenticate:代理服务器对客户端的认证信息

    • Retry-After:告知客户端应该在多久后再次发起请求。主要配合状态码503或3XX使用。

    • Server:HTTP服务器的安装信息

    • Vary:代理服务器缓存的管理信息

    • WWW-Authenticate:服务器对客户端的认证信息

  • 实体首部字段:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

    • Allow:资源可支持的HTTP方法

    • Content-Encoding:告知客户端服务器对实体主体部分选用的内容编码方式。

    • Content-Language:实体主体的自然语言

    • Content-Length:实体主体的大小(单位:字节)

    • Content-Location:报文主体返回资源对应的URI

    • Content-MD5:是由一串MD5算法生成的值,目的在于检查报文主体在传输过程中是否完整,以及确认传输送达。

    • Content-Range:告知客户端实体主体的位置范围

    • Content-Type:告知客户端实体主体的媒体类型

    • Expires:告知客户端实体主体过期的日期时间

    • Last-Mondified:资源的最后修改日期时间

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

端到端首部(End-to-end Header):
分在此类别的首部会转发给请求/响应的最终接收目标,且必须要存在由缓存生成的响应中,另外规定它必须被转发。

逐跳首部(Hop-by-hop Header):
分在此类别中的首部只对单词转发有效,会因通过缓存或代理而不再转发。在HTTP/1.1和之后的版本中,若要使用该类首部,需要提供Connection首部字段。

逐跳首部字段(未列出的均为端到端首部)

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

与Cookie相关的首部字段

  • Set-Cookie

    • NAME=VALUE : 赋予Cookie的名称和其值(必须项)
    • expires=DATE:Cookie的有效期(若不明确指定则默认为浏览器关闭前为止)
    • path=PATH:将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录)
    • domain=域名:作为Cookie适用对象的域名(若不指定则默认为创建Cookie的服务器的域名)
    • Secure:仅在HTTPS安全通信时才会发送Cookie
    • HttpOnly:加以限制,使Cookie不能被JavaScript脚本访问
  • Cookie

    首部字段会告知服务器,当客户端想要获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie,同样可以以多个Cookie形式发送。

HTTPS

什么是HTTPS?

超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种透过计算机网络进行安全通信的传输协议。HTTPS经由HTTP 进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。这个协议由网景公司(Netscape)在1994年首次提出,随后扩展到互联网上。

HTTPS 并非是应用层的一种新协议。只是HTTP通信接口部分用SSL( Secure Socket Layer)和 TLS( Transport Layer Security) 协议代替而已。

与HTTP的差异

与HTTP的URL由“http://”起始且默认使用端口80不同,HTTPS的URL由“https://”起始且默认使用端口443。

HTTP是不安全的,且攻击者通过监听和中间人攻击等手段,可以获取网站帐户和敏感信息等。HTTPS被设计为可防止前述攻击,并在正确配置时被认为是安全的。

HTTP中存在的缺点:

  • 通信适用明文(不加密),内容可能会被窃听
  • 不验证通信方的身份,因此可能遭遇伪装
  • 无法证明报文的完整性,所以有可能已遭篡改

秘钥加密

  • 共享密钥加密

    加密和解密同用一个密钥的方式称为共享密钥加密( Common keycrypto system),也被叫做对称密钥加密。在互联网上转发密钥时,如果通信被监听那么密钥就可会落入攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。

  • 公开密钥加密

    公开密钥加密使用一对非对称的密钥一把叫做私有密钥( private key),另一把叫做公开密钥( public key) 。 顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。 利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。

  • 混合加密机制

    HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制。若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。所以应充分利用两者各自的优势, 将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。

证书

证书的作用

公开密钥加密方式,无法证明公开密钥本身就是货真价实的公开密钥,可能会被篡改或者替换。为了解决上述问题,可以使用由数字证书认证机构( CA, CertificateAuthority)和其相关机关颁发的公开密钥证书。数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。

证书的种类

  • EV SSL 证书

    EV SSL证书是基于国际标准的认证指导方针颁发的证书,其严格规定了对运营组织是否真实的确认方针。因此,通过认证的Web网站能够获得更高的认可度。

  • 客户端证书

    HTTPS 中还可以使用客户端证书。以客户端证书进行客户端认证,证明服务器正在通信的对方始终是预料之内的客户端,其作用跟服务器证书如出一辙。安全性极高的认证机构可颁发客户端证书但仅用于特殊用途的业务。 比如那些可支撑客户端证书支出费用的业务。如:网银

  • 自签名证书

    如果使用OpenSSL这套开源程序,每个人都可以构建一套属于自己的认证机构,从而自己给自己颁发服务器证书。但该服务器证书在互联网上不可作为证书使用,似乎没什么帮助。独立构建的认证机构叫做自认证机构, 由自认证机构颁发的“无用”证书也被戏称为自签名证书。浏览器访问该服务器时,会显示“无法确认连接安全性”或“该网站的安全证书存在问题”等警告消息。