重要的概念和知识

1、URL和URI

HTTP 请求的内容通称为”资源”。”资源“这一概念非常宽泛,它可以是一份文档,一张图片,或所有其他你能够想到的格式。每个资源都由一个 (URI) 来进行标识。

一般情况下,资源的名称和位置由同一个 URL(统一资源定位符,它是 URI 的一种)来标识。也有某些特殊情况,资源的名称和位置由不同的 URI 进行标识:例如,待请求的资源希望客户端从另外一个位置访问它。我们可以使用一个特定的首部字段,Alt-Svc,来指示这种情况。

URL

URI 的最常见形式是统一资源定位符 (URL),它也被称为 Web 地址。

  1. https://developer.mozilla.org
  2. https://developer.mozilla.org/en-US/docs/Learn/
  3. https://developer.mozilla.org/en-US/search?q=URL

在浏览器的地址栏中输入上述任一地址,浏览器就会加载相应的网页(资源)。

URL 由多个必须或可选的组件构成。下面给出了一个复杂的 URL:

  1. http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
  • 方案或协议

http:// 告诉浏览器使用何种协议。对于大部分 Web 资源,通常使用 HTTP 协议或其安全版本HTTPS协议。另外,浏览器也知道如何处理其他协议。例如, mailto: 协议指示浏览器打开邮件客户端;ftp:协议指示浏览器处理文件传输。常见的方案有:

方案 描述
data Data URIs
file 指定主机上文件的名称
ftp 文件传输协议
http/https 超文本传输协议/安全的超文本传输协议
mailto 电子邮件地址
ssh 安全 shell
tel 电话
urn 统一资源名称
view-source 资源的源代码
ws/wss (加密的) WebSocket 连接
  • 主机

www.example.com 既是一个域名,也代表管理该域名的机构。它指示了需要向网络上的哪一台主机发起请求。当然,也可以直接向主机的 IP address 地址发起请求。但直接使用 IP 地址的场景并不常见。

  • 端口

:80 是端口。它表示用于访问 Web 服务器上资源的技术“门”。如果访问的该 Web 服务器使用HTTP协议的标准端口(HTTP为80,HTTPS为443)授予对其资源的访问权限,则通常省略此部分。否则端口就是 URI 必须的部分。

  • 路径

/path/to/myfile.html 是 Web 服务器上资源的路径。在 Web 的早期,类似这样的路径表示Web服务器上的物理文件位置。现在,它主要是由没有任何物理实体的 Web 服务器抽象处理而成的。

  • 查询

?key1=value1&key2=value2 是提供给 Web 服务器的额外参数。这些参数是用 & 符号分隔的键/值对列表。Web 服务器可以在将资源返回给用户之前使用这些参数来执行额外的操作。每个 Web 服务器都有自己的参数规则,想知道特定 Web 服务器如何处理参数的唯一可靠方法是询问该 Web 服务器所有者。

  • 片段

#SomewhereInTheDocument 是资源本身的某一部分的一个锚点。锚点代表资源内的一种“书签”,它给予浏览器显示位于该“加书签”点的内容的指示。 例如,在HTML文档上,浏览器将滚动到定义锚点的那个点上;在视频或音频文档上,浏览器将转到锚点代表的那个时间。值得注意的是 # 号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。

实例

  1. https://developer.mozilla.org/en-US/docs/Learn
  2. tel:+1-816-555-1212
  3. git@github.com:mdn/browser-compat-data.git
  4. ftp://example.org/resource.txt
  5. urn:isbn:9780141036144

URN

URN 是另一种形式的 URI,它通过特定命名空间中的唯一名称来标识资源。

  1. urn:isbn:9780141036144
  2. urn:ietf:rfc:7230

上面两个 URN 标识了下面的资源:

  • 乔治·奥威尔所著的《1984》
  • IETF规范7230,超文本传输协议 (HTTP/1.1):Message Syntax and Routing.

2、CGI

CGI是common gateway interface的缩写

web服务器所处理的内容都是静态的,要想处理动态内容,需要依赖于web应用程序,如php、jsp、python、perl等。但是web server如何将动态的请求传递给这些应用程序?它所依赖的就是cgi协议。没错,是协议,也就是web server和web应用程序交流时的规范。换句话说,通过cgi协议,再结合已搭建好的web应用程序,就可以让web server也能”处理”动态请求。

image.png

以PHP为例解释常用术语:

  • cgi:它是一种协议。通过cgi协议,web server可以将动态请求和相关参数发送给专门处理动态内容的应用程序。
  • fastcgi:也是一种协议,只不过是cgi的优化版。cgi的性能较烂,fastcgi则在其基础上进行了改进。
  • php-cgi:fastcgi是一种协议,而php-cgi实现了这种协议。不过这种实现比较烂。它是单进程的,一个进程处理一个请求,处理结束后进程就销毁。
  • php-fpm:是对php-cgi的改进版,它直接管理多个php-cgi进程/线程。也就是说,php-fpm是php-cgi的进程管理器因此它也算是fastcgi协议的实现。在一定程度上讲,php-fpm与php的关系,和tomcat对java的关系是类似的。
  • cgi进程/线程:在php上,就是php-cgi进程/线程。专门用于接收web server的动态请求,调用并初始化zend虚拟机。
  • cgi脚本:被执行的php源代码文件。
  • zend虚拟机:对php文件做词法分析、语法分析、编译成opcode,并执行。最后关闭zend虚拟机。
  • cgi进程/线程和zend虚拟机的关系:cgi进程调用并初始化zend虚拟机的各种环境。

以php-fpm为例,web server从转发动态请求到结束的过程大致如下:

image.png

而每个php-cgi进程的作用大致包括:

  1. 初始化php的各种相关变量
  2. 调用并初始化zend虚拟化
  3. 加载并解析php.ini
  4. 激活zend
    • zend加载a.php,并做词法/语法分析
    • 编译a.php脚本为opcode,并执行
    • 输出结果
    • 关闭zend虚拟机
  5. 返回结果给web server

3、HTTP如何并发的接收多个用户请求

http默认是工作在阻塞模型下的,默认一次只接收一个请求,处理完请求后再去接收下一个请求,所以只能一个一个来。

所以希望并发响应用户请求,需要多进程模型。 web 服务器自己会生成多个子进程响应用户请求,也就是说,当一个用户请求发到 Web 服务器, Web 主进程不会直接响应用户请求,而是生成一个子进程响应这个用户请求,这样当子进程和此用户建立连接之后。Web的主进程就会再等待另一个用户的请求,当第二个用户请求过来之后,再生成一个子进程响应第二个用户请求。以此类推。所以每一个用户请求都由一个子进程来处理。

HTTP协议基础

HTTP协议介绍

  • 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。
  • HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。
  • HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
  • HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
  • 在Internet中所有的传输都是通过TCP/IP进行的。HTTP协议作为TCP/IP模型中应用层的协议也不例外。HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。
  • HTTP默认的端口号为80,HTTPS的端口号为443。
  • 浏览网页是HTTP的主要应用,但是这并不代表HTTP就只能应用于网页的浏览。HTTP是一种协议,只要通信的双方都遵守这个协议,HTTP就能有用武之地。比如常用的QQ,迅雷这些软件,都会使用HTTP协议(还包括其他的协议)。

HTTP协议版本历史

HTTP/0.9

只支持GET方法,不支持MIM类型,服务器只能回应HTML格式的字符串,不能回应别的格式,当服务器发送完毕,就关闭TCP连接。

HTTP/1.0

  1. 引入了 MIME(Multipurpose Internet Mail Extesions)机制:多用途互联网邮件扩展,引入这个技术之后,http可以发送多媒体(比如视频、音频等)信息。此机制让http不再单单只支持html格式,还可以支持其他格式来进行发送了。
  2. 除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段
  3. HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
  4. 其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

HTTP/1.1

HTTP/1.1是目前主流的HTTP协议版本。之前的标准是RFC2068,之后又发布了修订版RFC2616

  1. 引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接
  2. 引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
  3. 将Content-length字段的作用进行扩充,即声明本次回应的数据长度(一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的)
  4. 采用分块传输编码,对于一些很耗时的动态操作,服务器需要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用”流模式”(stream)取代”缓存模式”(buffer)
  5. 新增了许多动词方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。另外,客户端请求的头信息新增了Host字段,用来指定服务器的域名

HTTP/2

2015年,HTTP/2 发布。它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3

  1. HTTP/2 的头信息是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”(frame):头信息帧和数据帧。
  2. HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了”队头堵塞”。
  3. 因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
  4. HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如Cookie和User Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。
  5. HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。

HTTP协议特点

HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。

HTTP协议的主要特点可概括如下:

  1. 支持客户/服务器模式。支持基本认证和安全认证
  2. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快
  3. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  4. HTTP 0.9和1.0使用非持续连接:限制每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接。HTTP 1.1使用持续连接:不必为每个web对象创建一个新的连接,一个连接可以传送多个对象,采用这种方式可以节省传输时间
  5. 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。

无状态协议:

协议的状态是指下一次传输可以“记住”这次传输信息的能力。
HTTP是不会为了下一次连接而维护这次连接所传输的信息,为了保证服务器内存。
比如客户获得一张网页之后关闭浏览器,然后再一次启动浏览器,再登陆该网站,但是服务器并不知道客户关闭了一次浏览器。由于Web服务器要面对很多浏览器的并发访问,为了提高Web服务器对并发访问的处理能力,在设计HTTP协议时规定Web服务器发送HTTP应答报文和文档时,不保存发出请求的Web浏览器进程的任何状态信息。这有可能出现一个浏览器在短短几秒之内两次访问同一对象时,服务器进程不会因为已经给它发过应答报文而不接受第二期服务请求。由于Web服务器不保存发送请求的Web浏览器进程的任何信息,因此HTTP协议属于无状态协议(Stateless Protocol)。

HTTP协议是无状态的和Connection: keep-alive的区别:

无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

HTML文本介绍

HTML文本架构

  1. <html>
  2. <head>
  3. <title>TITLE</title>
  4. </head>
  5. <body>
  6. <h1>H1</h1>
  7. <p></p>
  8. <h2>H2</h2>
  9. <p><a href="admin.html">ToGoogle</a> </p>
  10. </body>
  11. </html>

HTML文档生成方式

  • 静态:事先就编辑并定义完成的
  • 动态:通过编译语言编写的程序后输出html格式的结果。动态语言有: php, jsp, asp, .net,这些脚本都必须有相应的解释器,比如说php需要有php解释器等等。

静态和动态的方式

静态方式:
image.png

  1. Web 服务器向内核注册 socket
  2. 客户端通过浏览器,向 Web 服务器发起 request 请求
  3. Web 服务器收到客户端的 request 信息
  4. 如果用户请求的资源在服务器本地的话, http 服务会向系统内核申请调用
  5. 内核调用本地磁盘里的数据,并将数据发给 http 服务
  6. http 将用户请求的资源通过 response 报文,最终响应给客户端
    动态方式:
    image.png
    与静态不同的是,如果用户请求的是动态内容,那么此时http服务会调用后端的解析器,由动态语言去处理用户的请求,如果需要请求数据的时候,会向内核申请调用,从而向磁盘
    中获取用户指定的数据,通过解释器运行,运行的结果通常会生成 html 格式的文件。然后构建成响应报文,最终发回给客户端。

HTTP协议分析

HTTP的工作流程如下:

  1. 地址解析
    HTTP协议是通过标准URL()来请求指定服务器中的特定服务的。一个标准的URL如下:

    1. http://www.baidu.com:80/index.html?name=tom&age=18
    • http:协议类型。这里指的是要发送的是什么协议,还可以是FTP等其他协议 。而这里请求的是服务器中的网页,所以使用的是常见的HTTP协议。
    • www.baidu.com:主机名。通过主机名,可以准确定位到要访问的那台服务器。一般是域名,发送报文是需要解析成IP地址。
    • 80:端口号。代表特定的服务进程,通过端口号,可以找到服务器上的特定服务。80端口是Web服务器的默认端口,所以在写HTTP请求的URL的时候,80端口一般是省略的。
    • /index.html:路径名/文件名。通过文件名来访问指定的文件。
    • ?name=tom&age=18:请求参数。即使同一个网页,可能针对不同的用户,服务器要返回给客户端的信息也是不一样的。而服务器就是通过URL中“?”后面携带的参数不同来响应不同的用户或者同一个用户的不同请求的。
  2. 封装HTTP请求
    这一步把上面写的URL以及本机的一些信息封装成一个HTTP请求数据包
  3. 封装TCP包
    第三步就是封装TCP包 , 建立TCP连接 , 也就是常说的”三次握手”。
  4. 客户端发送请求命令
    客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
  5. 服务器端响应
    服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
  6. 关闭连接
    客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。如果此客户端请求的头部信息中有Connection-alive,那么客户端在响应完这个请求之后不会关闭连接,直到客户端的所有请求都响应完毕才会关闭连接,这样大大节省了带宽和IO资源。

HTTP协议消息

HTTP消息是服务器和客户端之间交换数据的方式。有两种类型的消息︰

  • 请求–由客户端发送用来触发一个服务器上的动作;
  • 响应–来自服务器的应答。

HTTP消息由采用ASCII编码的多行文本构成。在HTTP/1.1及早期版本中,这些消息通过连接公开地发送。在HTTP/2中,为了优化和性能方面的改进,曾经可人工阅读的消息被分到多个HTTP帧中。

HTTP 请求和响应具有相似的结构,由以下部分组成︰

  • 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个起始行总是单行的。
  • 一个可选的HTTP头集合指明请求或描述消息正文。
  • 一个空行指示所有关于请求的元数据已经发送完毕。
  • 一个可选的包含请求相关数据的正文(比如HTML表单内容),或者响应相关的文档。正文的大小有起始行的HTTP头来指定。

起始行和HTTP消息中的HTTP头统称为请求头,而其有效负载被称为消息正文。
image.png

HTTP请求

起始行

HTTP请求是由客户端发出的消息,用来使服务器执行动作。起始行 (start-line) 包含三个元素:

  1. 一个 HTTP 方法,一个动词 (像 GET, PUT 或者 POST) 或者一个名词 (像 HEAD 或者 OPTIONS), 描述要执行的动作. 例如, GET 表示要获取资源,POST 表示向服务器推送数据 (创建或修改资源, 或者产生要返回的临时文件)。
  2. 请求目标 (request target),通常是一个 URL,或者是协议、端口和域名的绝对路径,通常以请求的环境为特征。请求的格式因不同的 HTTP 方法而异。它可以是:

    • 一个绝对路径,末尾跟上一个 ’ ? ’ 和查询字符串。这是最常见的形式,称为 原始形式 (origin form),被 GET,POST,HEAD 和 OPTIONS 方法所使用。

      1. POST / HTTP 1.1
      2. GET /background.png HTTP/1.0
      3. HEAD /test.html?query=alibaba HTTP/1.1
      4. OPTIONS /anypage.html HTTP/1.0
    • 一个完整的URL,被称为绝对形式 (absolute form),主要在GET连接到代理时使用。

      1. GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
    • 由域名和可选端口(以’:’为前缀)组成的 URL 的 authority component,称为 authority form。 仅在使用 CONNECT 建立 HTTP 隧道时才使用。

      1. CONNECT developer.mozilla.org:80 HTTP/1.1
    • 星号形式 (asterisk form),一个简单的星号(’*’),配合 OPTIONS 方法使用,代表整个服务器。

      1. OPTIONS * HTTP/1.1
  3. HTTP 版本 (HTTP version),定义了剩余报文的结构,作为对期望的响应版本的指示符。

Headers

来自请求的 HTTP headers 遵循和 HTTP header 相同的基本结构:不区分大小写的字符串,紧跟着的冒号 (’:’) 和一个结构取决于 header 的值。 整个 header(包括值)由一行组成,这一行可以相当长。

有许多请求头可用,它们可以分为几组:

  • General headers,例如 Via,适用于整个报文。
  • Request headers,例如 User-Agent,Accept-Type,通过进一步的定义(例如 Accept-Language),或者给定上下文(例如 Referer),或者进行有条件的限制 (例如 If-None) 来修改请求。
  • Entity headers,例如 Content-Length,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
    image.png

Body

请求的最后一部分是它的 body。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。

Body 大致可分为两类:

  • Single-resource bodies,由一个单文件组成。该类型 body 由两个 header 定义: Content-Type 和 Content-Length.
  • Multiple-resource bodies,由多部分 body 组成,每一部分包含不同的信息位。通常是和 HTML Forms 连系在一起。

HTTP响应

状态行

HTTP 响应的起始行被称作 状态行 (status line),包含以下信息:

  1. 协议版本,通常为 HTTP/1.1。
  2. 状态码 (status code),表明请求是成功或失败。常见的状态码是 200,404,或 302。
  3. 状态文本 (status text)。一个简短的,纯粹的信息,通过状态码的文本描述,帮助人们理解该 HTTP 消息。

一个典型的状态行看起来像这样:HTTP/1.1 404 Not Found。

Headers

响应的 HTTP headers 遵循和任何其它 header 相同的结构:不区分大小写的字符串,紧跟着的冒号 (’:’) 和一个结构取决于 header 类型的值。 整个 header(包括其值)表现为单行形式。

有许多响应头可用,这些响应头可以分为几组:

  • General headers,例如 Via,适用于整个报文。
  • Response headers,例如 Vary 和 Accept-Ranges,提供其它不符合状态行的关于服务器的信息。
  • Entity headers,例如 Content-Length,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
    !image.png

Body

响应的最后一部分是 body。不是所有的响应都有 body:具有状态码 (如 201 或 204) 的响应,通常不会有 body。

Body 大致可分为三类:

  • Single-resource bodies,由已知长度的单个文件组成。该类型 body 由两个 header 定义:Content-Type 和 Content-Length。
  • Single-resource bodies,由未知长度的单个文件组成,通过将 Transfer-Encoding 设置为 chunked 来使用 chunks 编码。
  • Multiple-resource bodies,由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的。

HTTP/2帧

HTTP/1.x 报文有一些性能上的缺点:

  1. Header 不像 body,它不会被压缩。
  2. 两个报文之间的 header 通常非常相似,但它们仍然在连接中重复传输。
  3. 无法复用。当在同一个服务器打开几个连接时:TCP 热连接比冷连接更加有效。

HTTP/2 引入了一个额外的步骤:它将 HTTP/1.x 消息分成帧并嵌入到流 (stream) 中。数据帧和报头帧分离,这将允许报头压缩。将多个流组合,这是一个被称为 多路复用 (multiplexing) 的过程,它允许更有效的底层 TCP 连接。

image.png

HTTP 帧现在对 Web 开发人员是透明的。在 HTTP/2 中,这是一个在 HTTP/1.1 和底层传输协议之间附加的步骤。Web 开发人员不需要在其使用的 API 中做任何更改来利用 HTTP 帧;当浏览器和服务器都可用时,HTTP/2 将被打开并使用。

HTTP请求方法

在 HTTP 通信过程中,每个 HTTP 请求报文中都会包含一个 HTTP 请求方法,用于
告知客户端向服务器端请求执行某些具体的操作,下面列举几项常用的 HTTP 请
求方法。

GET

GET 方法请求指定的资源。使用 GET 的请求应该只用于获取数据。

  1. GET /index.html

HEAD

请求资源的头部信息, 并且这些头部与 HTTP GET 方法请求时返回的一致. 该请求方法的一个使用场景是在下载一个大文件前先获取其大小再决定是否要下载, 以此可以节约带宽资源。HEAD 方法的响应不应包含响应正文, 即使包含了正文也必须忽略掉。

  1. HEAD /index.html

POST

发送数据给服务器,请求主体的类型由 Content-Type 首部指定。一个 POST 请求通常是通过 HTML 表单发送, 并返回服务器的修改结果。服务器通常需要存储
此数据,通常存放在 mysql 这种关系型数据库中。

  1. POST /index.html

PUT

使用请求中的负载创建或者替换目标资源。服务器通常需要存
储此资源(存放的位置通常是文件系统)。
PUT 与 POST 方法的区别在于,PUT方法是幂等的:调用一次与连续调用多次是等价的(即没有副作用),而连续调用多次POST方法可能会有副作用,比如将一个订单重复提交多次。

  1. PUT /new.html HTTP/1.1

示例:

  • 请求
  1. PUT /new.html HTTP/1.1
  2. Host: example.com
  3. Content-type: text/html
  4. Content-length: 16
  5. <p>New File</p>
  • 应答

如果目标资源不存在,并且PUT方法成功创建了一份,那么源头服务器必须返回201 (Created) 来通知客户端资源已创建。

  1. HTTP/1.1 201 Created
  2. Content-Location: /new.html

如果目标资源已经存在,并且依照请求中封装的表现形式成功进行了更新,那么,源头服务器必须返回200 (OK) 或者204 (No Content) 来表示请求的成功完成。

  1. HTTP/1.1 204 No Content
  2. Content-Location: /existing.html

DELETE

用于删除指定的资源

  1. DELETE /file.html HTTP/1.1

示例:

  • 请求
  1. DELETE /file.html HTTP/1.1
  • 响应
    如果 DELETE 方法成功执行,那么可能会有以下几种状态码:
    • 状态码 202 (Accepted) 表示请求的操作可能会成功执行,但是尚未开始执行。
    • 状态码 204 (No Content) 表示操作已执行,但是无进一步的相关信息。
    • 状态码 200 (OK) 表示操作已执行,并且响应中提供了相关状态的描述信息。 ``` HTTP/1.1 200 OK Date: Wed, 21 Oct 2015 07:28:00 GMT

File deleted.

  1. <a name="OPTIONS"></a>
  2. ### OPTIONS
  3. 用于获取目的资源所支持的通信选项(支持的请求方法)。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将URL设置为“*”)使用该方法。

OPTIONS /index.html HTTP/1.1 OPTIONS * HTTP/1.1

  1. **示例:**<br />检测服务器所支持的请求方法

curl -X OPTIONS http://example.org -i

  1. 响应报文包含一个 Allow 首部字段,该字段的值表明了服务器支持的所有 HTTP 方法:

HTTP/1.1 200 OK Allow: OPTIONS, GET, HEAD, POST Cache-Control: max-age=604800 Date: Thu, 13 Oct 2016 11:45:00 GMT Expires: Thu, 20 Oct 2016 11:45:00 GMT Server: EOS (lax004/2813) x-ec-custom-error: 1 Content-Length: 0

  1. <a name="TRACE"></a>
  2. ### TRACE
  3. 实现沿通向目标资源的路径的消息环回(loop-back)测试 ,提供了一种实用的 debug 机制。

TRACE /index.html

  1. <a name="PATCH"></a>
  2. ### PATCH
  3. 用于对资源进行部分修改。
  4. 在HTTP协议中, PUT 方法已经被用来表示对资源进行整体覆盖, 而 POST 方法则没有对标准的补丁格式的提供支持。不同于 PUT 方法,而与 POST 方法类似,PATCH 方法是非幂等的,这就意味着连续多个的相同请求会产生不同的效果。

PATCH /file.txt HTTP/1.1

  1. <a name="CONNECT"></a>
  2. ### CONNECT
  3. 可以开启一个客户端与所请求资源之间的双向沟通的通道。它可以用来创建隧道(tunnel)。
  4. 例如,CONNECT 可以用来访问采用了 SSL (HTTPS) 协议的站点。客户端要求代理服务器将 TCP 连接作为通往目的主机隧道。之后该服务器会代替客户端与目的主机建立连接。连接建立好之后,代理服务器会面向客户端发送或接收 TCP 消息流。
  5. CONNECT 是一个应用范围为点到点的方法。

CONNECT www.example.com:443 HTTP/1.1

  1. **示例:**
  2. 一些代理服务器在创建隧道时会要求进行身份验证。参见 Proxy-Authorization 首部。

CONNECT server.example.com:80 HTTP/1.1 Host: server.example.com:80 Proxy-Authorization: basic aGVsbG86d29ybGQ=

  1. <a name="8c9d507e"></a>
  2. ### 总结:
  3. 常用的 HTTP 请求方式是 GET, POST, HEAD
  4. <a name="3447c9e5"></a>
  5. # HTTP响应状态码
  6. <a name="83c460f8"></a>
  7. ## 状态代码含义
  8. 状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
  9. - 1XX:指示信息,表示请求已接收,继续处理
  10. - 2XX: 响应成功,表示动作被成功接收、理解和接受
  11. - 3XX: 重定向类,为了完成指定的动作,必须接受进一步处理
  12. - 4XX: 客户端错误类,请求包含错误语法或不能正确执行
  13. - 5XX: 服务端错误类,服务器不能正确执行一个正确的请求
  14. <a name="64bb0f5d"></a>
  15. ## 常用状态码说明
  16. - 200:服务器成功返回网页,这是成功的 HTTP 请求返回的标准状态码
  17. - 201:Created 是一个代表成功的应答状态码,表示请求已经被成功处理,并且创建了新的资源
  18. - 301:永久重定向 说明请求的资源已经被移动到了由 Location 头部指定的url上,是固定的不会再改变。搜索引擎会根据该响应修正
  19. - 302:Found 重定向状态码表明请求的资源被暂时的移动到了由Location 头部指定的 URL 上。浏览器会重定向到这个URL, 但是搜索引擎不会对该资源的链接进行更新
  20. - 304:未改变,说明无需再次传输请求的内容,也就是说可以使用缓存的内容
  21. - 403:Forbidden 代表客户端错误,指的是服务器端有能力处理该请求,但是拒绝授权访问。
  22. - 404:Not Found 代表客户端错误,指的是服务器端无法找到所请求的资源。404 状态码并不能说明请求的资源是临时还是永久丢失。如果服务器知道该资源是永久丢失,那么应该返回 410 (Gone) 而不是 404 。
  23. - 405:Method Not Allowed 表明服务器禁止了使用当前 HTTP 方法的请求。需要注意的是,GET 与 HEAD 两个方法不得被禁止,当然也不得返回状态码 405。
  24. - 500:Internal Server Error 是表示服务器端错误的响应状态码,意味着所请求的服务器遇到意外的情况并阻止其执行请求。
  25. - 502:Bad Gateway 是一种HTTP协议的服务器端错误状态代码,它表示作为网关或代理角色的服务器,从上游服务器(如tomcat、php-fpm)中接收到的响应是无效的。
  26. - 503:Service Unavailable 是一种HTTP协议的服务器端错误状态代码,它表示服务器尚未处于可以接受请求的状态。通常造成这种情况的原因是由于服务器停机维护或者已超载。
  27. <a name="6b303b99"></a>
  28. # HTTP头部介绍
  29. <a name="17a0497d"></a>
  30. ## 通用头部(General headers)
  31. <a name="Connection"></a>
  32. #### Connection
  33. 控制网络连接是否保持打开状态,当前事务结束之后。如果发送的值是keep-alive,则连接是持久的而不是关闭的,允许对同一服务器的后续请求进行。不能和HTTP/2一起使用。

Connection: keep-alive Connection: close

  1. <a name="Cache-Control"></a>
  2. #### Cache-Control
  3. 用于在请求和响应报文中定义缓存机制的指令。缓存指令是单向的,这意味着请求中的给定指令并不意味着在响应中给出相同的指令。
  4. **用于客户端请求报文语法**:

Cache-Control: max-age= Cache-Control: max-stale[=] Cache-Control: min-fresh= Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: only-if-cached

  1. **用于服务器响应报文语法**:

Cache-Control: must-revalidate Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: public Cache-Control: private Cache-Control: proxy-revalidate Cache-Control: max-age= Cache-Control: s-maxage=

  1. 具体信息:[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)
  2. <a name="1a35ddfc"></a>
  3. ## 请求头部(Request headers)
  4. <a name="Host"></a>
  5. #### Host
  6. 指定服务器的域名(虚拟主机),和(可选的)TCP端口号。

Host: :

  1. 例如:

Host: developer.cdn.mozilla.net

  1. <a name="Referer"></a>
  2. #### Referer
  3. 包含上一个网页的地址,从该网页链接到当前请求的网页。允许服务器识别人们从何处访问他们,并可以使用这些数据进行分析、日志记录或优化缓存。有时也被用作防盗链, 即下载时判断来源地址是不是在网站域名之内, 否则就不能下载或显示。

Referer:

  1. 例如:

Referer: https://developer.mozilla.org/en-US/docs/Web/JavaScript

  1. <a name="User-Agent"></a>
  2. #### User-Agent
  3. 内容是特定字符串,包含用户代理的应用程序类型、操作系统、软件供应商或请求软件的版本(一般是浏览器)

User-Agent: /

  1. 用于浏览器通用格式:

User-Agent: Mozilla/ () ()

  1. <a name="Accept"></a>
  2. #### Accept
  3. 客户端可以理解的MIME类型

Accept: / Accept: / Accept: /*

// Multiple types, weighted with the quality value syntax: Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, /;q=0.8

  1. 示例:

Accept: text/html

Accept: image/*

// General default Accept: /

// Default for navigation requests Accept: text/html, application/xhtml+xml, application/xml;q=0.9, /;q=0.8

  1. <a name="Accept-Charset"></a>
  2. #### Accept-Charset
  3. 客户端可以理解的字符集

Accept-Charset:

// Multiple types, weighted with the quality value syntax: Accept-Charset: utf-8, iso-8859-1;q=0.5

  1. 示例:

Accept-Charset: iso-8859-1

Accept-Charset: utf-8, iso-8859-1;q=0.5

Accept-Charset: utf-8, iso-8859-1;q=0.5, *;q=0.1

  1. <a name="Accept-Encoding"></a>
  2. #### Accept-Encoding
  3. 客户端可以理解的编码格式,通常是一种压缩算法。

Accept-Encoding: gzip Accept-Encoding: compress Accept-Encoding: deflate Accept-Encoding: br Accept-Encoding: identity Accept-Encoding: *

// Multiple algorithms, weighted with the quality value syntax: Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5

  1. 示例:

Accept-Encoding: gzip

Accept-Encoding: gzip, compress, br

Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1

  1. <a name="Accept-Language"></a>
  2. #### Accept-Language
  3. 客户端能够理解哪些语言,以及首选哪种语言环境变量。(指的是自然语言,如英语,而不是编程语言。)

Accept-Language: Accept-Language: *

// Multiple types, weighted with the quality value syntax: Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5

  1. 示例:

Accept-Language: de

Accept-Language: de-CH

Accept-Language: en-US,en;q=0.5

  1. <a name="4b81c0a0"></a>
  2. #### 条件式请求首部
  3. (在 http1.1 中才会用到),当发送请求时,先问问对方是否满足条件,如果满足条件就请求,不满足就不请求
  4. - If-Match
  5. - If-Modified-Since
  6. - If-None-Match
  7. - If-Range
  8. - If-Unmodified-Since
  9. <a name="Authorization"></a>
  10. #### Authorization
  11. 包含用于向服务器验证用户代理的凭据

Authorization:

  1. 示例:

Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

  1. <a name="Cookie"></a>
  2. #### Cookie
  3. 内容包含服务器使用Set-Cookie头发送过来的被存储的HTTP cookies。

Cookie: Cookie: name=value Cookie: name=value; name2=value2; name3=value3

  1. 示例:

Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;

  1. <a name="4e1a6482"></a>
  2. ## 响应头部(Response headers)
  3. <a name="Age"></a>
  4. #### Age
  5. 内容为对象在代理缓存中的时间(秒)。通常值接近为0,如果是0,说明可能是从源服务器获取的。

Age:

  1. 示例:

Age: 24

  1. <a name="Server"></a>
  2. #### Server
  3. 包含有关原始服务器用于处理请求的软件的信息

Server:

  1. 示例:

Server: Apache/2.4.1 (Unix)

  1. <a name="Vary"></a>
  2. #### Vary
  3. 决定如何匹配未来的请求头,以决定是否可以使用缓存的响应,而不是从源服务器请求新的响应。服务器使用它来指示在内容协商算法中选择资源表示形式时使用哪种头。

Vary: * Vary: , , …

  1. <a name="WWW-Authenticate"></a>
  2. #### WWW-Authenticate
  3. 定义访问资源时应使用的身份验证方法

WWW-Authenticate: realm=

  1. 示例:

WWW-Authenticate: Basic

WWW-Authenticate: Basic realm=”Access to the staging site”, charset=”UTF-8”

  1. <a name="Set-Cookie"></a>
  2. #### Set-Cookie
  3. 用于从服务器发送cookies到用户代理(浏览器)

Set-Cookie: = Set-Cookie: =; Expires= Set-Cookie: =; Max-Age= Set-Cookie: =; Domain= Set-Cookie: =; Path= Set-Cookie: =; Secure Set-Cookie: =; HttpOnly

Set-Cookie: =; SameSite=Strict Set-Cookie: =; SameSite=Lax

// Multiple directives are also possible, for example: Set-Cookie: =; Domain=; Secure; HttpOnly

  1. 示例:
  2. Session cookie

Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/

  1. Permanent cookie

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

  1. Invalid domains

Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT

  1. Cookie prefixes

// Both accepted when from a secure origin (HTTPS) Set-Cookie: Secure-ID=123; Secure; Domain=example.com Set-Cookie: Host-ID=123; Secure; Path=/

// Rejected due to missing Secure directive Set-Cookie: __Secure-id=1

// Rejected due to the missing Path=/ directive Set-Cookie: __Host-id=1; Secure

// Rejected due to setting a domain Set-Cookie: __Host-id=1; Secure; Path=/; domain=example.com

  1. <a name="Location"></a>
  2. #### Location
  3. 定义将一个页面重定向到的URL。只在3xx(重定向)和201(创建)响应码中使用才有意义。

Location:

  1. 示例:

Location: /index.html

  1. <a name="ETag"></a>
  2. #### ETag
  3. 是资源特定版本的标识符。它允许缓存内容以便更高效,并节省带宽,因为如果内容没有更改,Web服务器不需要发送完整的响应。另一方面,如果内容发生了变化,etags有助于防止同时更新的资源相互覆盖。
  4. 在网络上,有一些缓存服务器,另外,浏览器自身也有缓存功能,<br />基于一个前提:图片不会经常改动,服务器在返回状态码 200 的同时,还会返回该图片的签<br />名 Etag,(可以理解为图片的指纹), 当浏览器再次访问该图片时,就会去服务器校验指纹信息,<br />如果图片没有变化,直接使用缓存里的图片,这样减轻了服务器的负担, 一看到 304,浏览<br />器就知道了,要从本地缓存里面取图片,节省了图片在网络上传输的时间。

ETag: W/““ ETag: “

  1. 示例:

ETag: “33a64df551425fcc55e4d42a148795d9f25f89d4” ETag: W/“0815”

  1. <a name="Expires"></a>
  2. #### Expires
  3. 包含将响应视为过期的日期/时间。
  4. 无效日期(如值0)表示过去的日期,表示资源已过期。

Expires:

  1. 示例:

Expires: Wed, 21 Oct 2015 07:28:00 GMT

  1. <a name="Last-Modified"></a>
  2. #### Last-Modified
  3. 包含源服务器认为资源上次被修改的日期和时间。它用作验证器来确定接收或存储的资源是否相同。比ETag头精确度低,它是一种回退机制。

Last-Modified: , :: GMT

  1. 示例:

Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

  1. <a name="5e28cc43"></a>
  2. ## 实体头部(Entity headers)
  3. <a name="Allow"></a>
  4. #### Allow
  5. 列出资源支持的一组方法

Allow:

  1. 示例:

Allow: GET, POST, HEAD

  1. <a name="Content-Encoding"></a>
  2. #### Content-Encoding
  3. 是用来压缩媒体类型的。当存在时,它的值是定义了哪种编码应用于Entiry-body。

Content-Encoding: gzip Content-Encoding: compress Content-Encoding: deflate Content-Encoding: identity Content-Encoding: br

// Multiple, in the order in which they were applied Content-Encoding: gzip, identity Content-Encoding: deflate, gzip

  1. <a name="Content-Language"></a>
  2. #### Content-Language
  3. 用于描述面向受众的语言,以便用户根据自己的首选语言用于区分的依据。例如:如果设置了Content-Language: de-DE,则表示文档是为德语使用者编写的(但是,它并不表示文档是用德语编写的),如果要指示文档所用的语言,在HTML文档中使用:

  1. 语法:

Content-Language: de-DE Content-Language: en-US Content-Language: de-DE, en-CA

  1. <a name="Content-Length"></a>
  2. #### Content-Length
  3. 定义发送给接收者的实体内容大小(字节byte为单位)

Content-Length:

  1. <a name="Content-Location"></a>
  2. #### Content-Location
  3. 定义一个返回数据的轮替location,主要用于被传输的资源的URL,这是内容协商的结果。Request header|
  4. Location和Content-Location不同,location表示重定向的URL,而Content-Location用于访问资源的直接URL,以后不再进行内容协商。

Content-Location:

  1. **示例:**
  2. **以不同格式向服务器请求数据,服务器返回的也不同**
  3. | Request header | Response header |
  4. | --- | --- |
  5. | Accept: application/json, text/json | Content-Location: /documents/foo.json |
  6. | Accept: application/xml, text/xml | Content-Location: /documents/foo.xml |
  7. | Accept: text/plain, text/* | Content-Location: /documents/foo.txt |
  8. **指向新的文档**
  9. 如果你通过server API创建了一个新的博客

PUT /new/post Host: example.com Content-Type: text/markdown

My first blog post!

I made this through example.com‘s API. I hope it worked.

  1. 服务器返回一个消息确认发布成功

HTTP/1.1 201 Created Content-Type: text/plain; charset=utf-8 Content-Location: /my-first-blog-post

✅ Success!

  1. <a name="Content-Type"></a>
  2. #### Content-Type
  3. 用于指定资源媒体类型

Content-Type: text/html; charset=utf-8 Content-Type: multipart/form-data; boundary=something

  1. **示例:**
  2. 请求的Content-Type
  3. 中的enctype属性指定:

  1. 请求看起来像这样:(这里省略了部分信息)

POST /foo HTTP/1.1 Content-Length: 68137 Content-Type: multipart/form-data; boundary=—————————————-974767299852498929531610575

——————————————-974767299852498929531610575 Content-Disposition: form-data; name=”description”

some text ——————————————-974767299852498929531610575 Content-Disposition: form-data; name=”myFile”; filename=”foo.txt” Content-Type: text/plain

(content of the uploaded file foo.txt) ——————————————-974767299852498929531610575—

  1. <a name="ed25b1b3"></a>
  2. ## 扩展头部()
  3. <a name="a72bbde2"></a>
  4. ## MIME类型
  5. 媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。它在IETF RFC 6838中进行了定义和标准化。
  6. 浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要。如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。
  7. <a name="f2b0b493"></a>
  8. ### 语法
  9. <a name="3e6b64cb"></a>
  10. #### 通用结构

type/subtype

  1. MIME的组成结构非常简单;由类型与子类型两个字符串中间用’/'分隔而组成。不允许空格存在。type 表示可以被分多个子类的独立类别。subtype表示细分后的每个类型。
  2. MIME类型对大小写不敏感,但是传统写法都是小写。
  3. <a name="7578cb5c"></a>
  4. #### 独立结构

text/plain text/html image/jpeg image/png audio/mpeg audio/ogg audio/ video/mp4 application/ application/json application/javascript application/ecmascript application/octet-stream …

  1. 独立类型表明了对文件的分类,可以是如下之一:
  2. | | | 典型实例 |
  3. | --- | --- | --- |
  4. | text | 表明文件是普通文本,理论上是人类可读 | text/plain, text/html, text/css, text/javascript |
  5. | image | 表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型 | image/gif,image/png,image/jpeg,image/bmp,image/webp,image/x-icon, image/vnd.microsoft.icon |
  6. | audio | 表明是某种音频文件 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav |
  7. | video | 表明是某种视频文件 | video/webm, video/ogg |
  8. | application | 表明是某种二进制数据 | application/octet-stream,application/pkcs12,application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf |
  9. 对于text文件类型若没有特定的subtype,就使用 text/plain。类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream
  10. <a name="7f7a8b55"></a>
  11. #### Multipart 类型

multipart/form-data multipart/byteranges

  1. Multipart 类型表示细分领域的文件类型的种类,经常对应不同的 MIME 类型。这是复合文件的一种表现方式。multipart/form-data 可用于HTML Forms POST 方法,此外 multipart/byteranges使用状态码206 Partial Content来发送整个文件的子集,而HTTP对不能处理的复合文件使用特殊的方式:将信息直接传送给浏览器(这时可能会建立一个“另存为”窗口,但是却不知道如何去显示内联文件。)
  2. <a name="0a0a7e69-1"></a>
  3. ## HTTP协议分析
  4. <a name="adaafda3"></a>
  5. ### 1、利用wireshark分析HTTP协议
  6. <a name="79e1bb3f"></a>
  7. #### 清空缓存
  8. 在进行跟踪之前,我们首先清空 Web 浏览器的高速缓存来确保Web网页是从网络中获取的,而不是从高速缓冲中取得的。之后,还要在客户端清空DNS高速缓存,来确保Web服务器域名到IP地址的映射是从网络中请求。
  9. <a name="be16af8e"></a>
  10. #### 开始俘获
  11. 1. 在菜单中选择 capture-options,选择网络,打开 start
  12. 1. 在浏览器地址栏中输入 www.sina.com.cn,然后点击“NBA”,然后结束俘获。
  13. 1. 在过滤器中选择HTTP,点击apply,得到如下结果:<br />![](https://tvax1.sinaimg.cn/large/005BYqpggy1g4k39uexzhj31g30ppakx.jpg#id=mcn60&originHeight=925&originWidth=1875&originalType=binary&ratio=1&status=done&style=none)
  14. 1. 分析数据
  15. - 在协议框中选择“GET /NBA/ HTTP/1.1”所在的分组会看到这个基本请求行后跟随着一系列额外的请求首部。
  16. - 在首部后的“\r\n”表示一个回车和换行,以此将该首部与下一个首部隔开。
  17. - Host”首部在 HTTP1.1 版本中是必须的,它描述了 URL 中机器的域名,本测试中是<br />sports.sina.com.cn。这就允许了一个 Web 服务器在同一时间支持许多不同的域名。有了这个首部, Web 服务器就可以区别客户试图连接哪一个 Web 服务器,并对每个客户响应不同的内容。
  18. - User-Agent 首部描述了提出请求的 Web 浏览器及客户机器。
  19. - 接下来是一系列的 Accpet 首部,包括 Accept(接受)、 Accept-Language(接受语言)、<br />Accept-Encoding(接受编码)、 Accept-Charset(接受字符集)。它们告诉 Web服务器客户Web浏览器准备处理的数据类型。Web服务器可以将数据转变为不同的语言和格式。这些首部表明了客户的能力和偏好
  20. - Keep-Alive Connection 首部描述了有关 TCP 连接的信息,通过此连接发送 HTTP 请求和响应。它表明在发送请求之后连接是否保持活动状态及保持多久。大多数HTTP1.1连接是持久的(persistent),意思是在每次请求后不关闭TCP连接,而是保持该连接以接受从同一台服务器发来的多个请求。
  21. - 观察Web服务器的应答。响应首先发送“HTTP/1.1 200 ok”,指明它开始使用HTTP1.1版本来发送网页。同样,在响应分组中,它后面也跟随着一些首部。最后,被请求的实际数据被发送。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12888578/1635345747614-e7ad94bc-d808-490e-9808-5ad4d164c642.png#clientId=u845c67cc-57b3-4&from=paste&id=u36555818&margin=%5Bobject%20Object%5D&name=image.png&originHeight=800&originWidth=1893&originalType=url&ratio=1&size=948989&status=done&style=none&taskId=u9119a46f-405f-46a7-a5ce-47279493117)<br />Cache-control 首部,<br />用于描述是否将数据的副本存储或高速缓存起来,以便将来引用。一般个人的 Web 浏览器<br />会高速缓存一些本机最近访问过的网页,随后对同一页面再次进行访问时,如果该网页仍存<br />储于高速缓存中,则不再向服务器请求数据。在 HTTP 请求中, Web 服务器列出内容类型及<br />可接受的内容编码。此例中 Web 服务器选择发送内容的类型是 text/html
  22. <a name="6521f650"></a>
  23. ### 2、curl查看HTTP响应头信息
  24. <a name="212cd029"></a>
  25. #### 客户端(浏览器)从服务器请求数据经历如下基本步骤:
  26. 1. 用户发起一个http请求,缓存获取到URL,根据URL查找是否有匹配的副本,这个副本可能在内存中,也可能在本地磁盘
  27. 1. 如果请求命中本地缓存则从本地缓存中获取一个对应资源的"copy"
  28. 1. 检查这个"copy"是否过期,否则直接返回,是则继续向服务器转发请求。 HTTP 中,通过Cache-Control 首部和 Expires首部为文档指定了过期时间,通过对过期时间的判断,缓<br />存就可以知道文档是不是在保质期内。 Expires首部和Cache-Control:max-age 首部都是来告诉缓存文档有没有过期,为什么需要两个响应首部来做这件简单的事情了?其实这一切都是历史原因, Expires 首部是 HTTP 1.0 中提出来的,因为他使用的是绝对日期,如果服务端和客户端时钟不同步的话(实际上这种情况非常常见),缓存可能就会认为文档已经<br />过了保质期。
  29. 1. 服务器接收到请求,然后判断资源是否变更,是则返回新内容,否则返回 304,未变更,更新过期时间<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12888578/1635345754401-3e8cd3a8-1211-4d25-9204-62582f2dc67c.png#clientId=u845c67cc-57b3-4&from=paste&id=uff360e67&margin=%5Bobject%20Object%5D&name=image.png&originHeight=790&originWidth=1074&originalType=url&ratio=1&size=540215&status=done&style=none&taskId=u9c2e707c-a829-480b-83cd-2a2da322173)
  30. <a name="a87d7e60"></a>
  31. #### 通过curl访问百度网站
  32. ```linux
  33. [root@shengzhe ~]# curl -I http://www.baidu.com
  34. HTTP/1.1 200 OK
  35. Accept-Ranges: bytes
  36. Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
  37. Connection: Keep-Alive
  38. Content-Length: 277
  39. Content-Type: text/html
  40. Date: Mon, 01 Jul 2019 02:15:20 GMT
  41. Etag: "575e1f60-115"
  42. Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
  43. Pragma: no-cache
  44. Server: bfe/1.0.8.18

HTTP响应头的信息:

  1. HTTP返回码:
    • 1XX:指示信息,表示请求已接收,继续处理
    • 2XX: 响应成功,表示动作被成功接收、理解和接受
    • 3XX: 重定向类,为了完成指定的动作,必须接受进一步处理
    • 4XX: 客户端错误类,请求包含错误语法或不能正确执行
    • 5XX: 服务端错误类,服务器不能正确执行一个正确的请求
  2. Cache-Control
    web站点对缓存的设置:Cache-Control 指定请求和响应遵循的缓存机制,缓存分类:
    • 私有缓存:常见就是我们的浏览器里内置的缓存。
    • 公有缓存:常见的就是代理缓

Cache-Control可选的参数:private、 public 、 no-cache、 max-age、 must-revalidate等

  • no-cache:响应不会被缓存,而是实时向服务器端请求资源
  • no-store: 在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。
  • Private: 指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当前用户的部分响应消息,此响应消息对于其他用户的请求无效。 不能再用户间共享。
  • Public:响应会被缓存,并且在多用户间共享。正常情况, 如果要求 HTTP 认证,响应会自动设置为 private。
  • max-age: 指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应, 例如:
    Cache-control: max-age=5 表示当访问此网页后的 5 秒内再次访问不会去服务器。
  • must-revalidate : 响应在特定条件下会被重用,以满足接下来的请求,但是它必须到服务器
    端去验证它是不是仍然是最新的( 强制所有缓存都验证响应)。
  • proxy-revalidate : 类似于 must-revalidate,它要求对公共缓存进行验证
  1. Connection:
    server 是否支持长连接;如果 keep-alive 说明 web 的 server 支持长连接。但是TCP的长连接是双向的;必须是client和server都支持长连接;才可以建立长连接。一般client(浏览器)都是默认支持长连接;所以只要 sever端支持长连接;就可以建立长连接。

通过 curl 的-w 参数我们可以自定义 curl 的输出, %{http_code}代表 http 状态码

  1. [root@shengzhe ~]# curl -I -o /dev/null -s -w %{http_code}"\n" www.baidu.com
  2. 200