HTTP知识点——(一)

虽然我们有B/S(Browser/Server)结构、C/S(Client/Server)结构这样的说法来区分浏览器-服务器通信和客户端-服务器通信,不过说到底只要是通过发送请求获取服务器资源的一方,无论是Web浏览器还是移动App抑或是桌面应用,其实都可以算是客户端。而Web使用名为HTTP(HyperText Transfer Protocol,超文本传输协议)的协议作为规范,来完成从客户端到服务器端的一系列操作流程。所谓协议,便是规则的约定,是一些既定的标准,我们这些开发者,只要遵守并好好使用就是了。不过说到HTTP么还是要先说下TCP/IP协议族。

TCP/IP协议族

通常所说的网络(包括互联网),是在TCP/IP协议族的基础上运作的,而HTTP是它的一个子集。TCP/IP协议族可以分为4层,分别是应用层、传输层、网络层和链路层。下面分别介绍一下各层的作用:

  • 应用层:决定了向用户提供应用服务时通信的活动。FTP(File Transfer Protocol, 文件传输协议)、DNS(Domain Name System,域名系统)和HTTP都属于该层。
  • 传输层:提供处于网络连接中的两台计算机之间的数据传输。TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据协议)都属于该层。
  • 网络层:用来处理网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
  • 链路层:用来处理网络的硬件部分,包括操作系统、硬件的设备驱动、NIC(Network Interface Card,网卡)、光纤、诸如连接器之类的传输媒介等物理可见部分。

URI和URL

URI表示统一资源标识符,是Uniform Resource Identifier的缩写。RFC2396(RFC,Request for Comments,征求修正意见书,一些指定HTTP协议技术标准的文档)分别对这三个单词进行了如下定义:

  • Uniform:规定统一的格式可方便处理多种不同类型的资源,而不用根据上下文环境来识别资源指定的访问方式。另外,加入新增的协议方案(如http:或ftp:)也更容易。

  • Resource:资源的定义是“可标识的任何东西”。资源不仅可以是单一的,也可以是个集合体。

  • Identifier:用来表示可标识的对象。也称为标识符。

综上所述,URI就是由某个协议方案(如http、ftp)表示的资源的定位标识符。如下列举几种URI的例子:

ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
ldap://[2001:db8::7]/c=GB?objectClass?one
mailto:John.Doe@example.com
tel:+1-816-555-1212

URI用字符串标识某一互联网资源,而我们相对来说更熟悉的URL(UniformResource Locator,统一资源定位符)则是表示资源的地点。显然URL是URI的子集,而在我们大部分日常使用场景下,说到URL和URI的时候其实表示的是一个意思。


三次握手

我们知道TCP和UDP主要的区别是UDP只负责发送,不确保一定送达;而TCP提供可靠的字节流服务(Byte Stream Service),采用三次握手策略确保数据送达。三次握手的过程使用了TCP 标志——SYN(synchronize)和ACK(acknowledgement):

  1. 发送端发送一个带SYN标志的数据包给对方。
  2. 接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。
  3. 发送端回传一个带ACK标志的数据包,表示握手结束。

HTTP通信

利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通讯。以HTTP举例来说,过程是这样的:

  1. 客户端在应用层(HTTP协议)发出一项想看某个Web页面的HTTP请求
  2. 在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。
  3. 在网络层(IP协议),增加作为通信目的地MAC地址后转发给链路层。

经过以上步骤,一个网络请求就准备齐全了。经过网络传输之后,接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。到了应用层才算真正接收到由客户端发送过来的HTTP请求。

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

HTTP请求


HTTP协议用于客户端与服务器端之间的通信,协议规定,请求从客户端发出,最后服务器端响应该请求并返回。来看一个请求报文的例子:

GET /search.jsp HTTP/1.1
Host: g.hxgoogle.com

起始行的GET是一个HTTP动词,也称为方法(method),它可以指定请求的资源按期望产生某种行为,随后的字符串/search.jsp指明了请求访问的资源对象,称为请求URI(request-URI),HTTP/1.1即HTTP的版本号,用来提示客户端使用的HTTP协议功能。所以这段报文的意思翻译一下是这样的:请求用GET方法访问域名为g.hxgoogle.com的服务器上的/search.jsp页面资源。

一个完整的请求报文由Header和Body组成,Header包括请求方法、请求URI、协议版本、可选的请求首部字段等,Body指报文主体。下面重点介绍一下请求URI和HTTP方法。

一个请求报文的例子:

请求头部:位于请求行的下面

请求报文中常见的标头有:

Connetion标头(连接管理)、Host标头(指定请求资源的主机)、Range标头(请求实体的字节范围)、User-Agent标头(包含发出请求的用户信息)、Accept标头(首选的媒体类型)、Accept-Language(首选的自然语言)

HTTP首部:

通用首部:请求和响应都可以使用的;

Connection:定义C/S之间关于请求/响应的有关选项对于http/1.0, Connection:keep-aliveVia: 显示了报文经过的中间节点

Cache-Control: 缓存指示

实体首部:用于指定实体属性

实体主体用于POST方法中。用户向Web服务器提交表单数据的时候,需要使用POST方法,此时主体中包含用户添写在表单的各个属性字段的值,当Web服务器收到POST方法的HTTP请求报文后,可以从实体中取出需要的属性字段的值。也就是说,当用户通过Web浏览器向Web服务器发送请求时,Web浏览器会根据用户的具体请求来选择不同的HTTP请求方法,再将相应的URL和HTTP协议版本及相关的标头填入头部行中,若是POST方法,还会将相关的表单数据填入实体主体中,产生一个HTTP请求报文,然后将这个报文发送给Web服务器。

 

Location: 资源的新位置Allow:允许对此资源使用的请求方法1、内容首部:Content-Encoding:支持的编码Content-Language:支持的自然语言Content-Length:文本长度Content-Location:资源所在位置Content-Range:在整个资源中此实体表示的字节范围

Content-Type:主体的对象类型

2、缓存首部:ETag: 实体标签Expires: 过期期限Last-Modified: 上一次的修改时间

请求首部:

Host: 请求的主机名和端口号,虚拟主机环境下用于不同的虚拟主机Referer:指明了请求当前资源的原始资源的URL

User-Agent: 用户代理,使用什么工具发出的请求

1、Accept首部:用户标明客户自己更倾向于支持的能力Accept: 指明服务器能发送的媒体类型Accept-Charset:支持使用的字符集Accept-Encoding: 支持使用的编码方式

Accept-Language: 支持使用语言

2、条件请求首部:Expect: 告诉服务器能够发送来哪些媒体类型If-Modified-Since:是否在指定时间以来修改过此资源If-None-Match:如果提供的实体标记与当前文档的实体标记不符,就获取此文档跟安全相关的请求首部:Authorization:客户端提交给服务端的认证数据,如帐号和密码

Cookie: 客户端发送给服务器端身份标识


HTTP方法

我们最常用的HTTP方法是GET和POST,这导致很多人以为HTTP方法只有GET和POST。这是不对的,这些年RESTful API非常流行,所以作为Web开发人员至少还应该知道PUT和DELETE。当然HTTP方法并不只有这么几种,下面介绍几种HTTP/1.1中的方法:

  • GET:请求访问已被URI识别的资源,资源经服务器端解析后返回响应内容。
  • POST:虽然GET方法也可以在Body中包含内容进行传输,不过一般不用,而是使用POST方法。POST在RESTful架构中一般用来修改资源。
  • PUT:用于传输资源到URI指定位置进行保存。由于PUT方法自身不带验证机制,存在安全问题,因此一般Web网站不使用该方法。若配合Web应用程序的验证机制或采用RESTful架构设计,可能会开放使用。PUT在RESTful架构中一般用来添加资源。
  • DELETE:删除资源。与PUT情况类似,一般不开放。
  • HEAD:获得报文首部(Header),用于确认URI的有效性及资源的更新日期等。
  • TRACE:追踪路径。发送请求时,在请求Header中加上Max-Forwards字段,譬如Max-Forwards: 2这样,每经过一个服务器就将该数字减1,当数字为0时停止传输,最后接收到请求的服务器返回状态码200 OK响应,响应包含最初的请求内容(将HTTP请求原样返回)。
  • CONNECT:要求在于代理服务器通信时建立隧道,用隧道协议进行TCP通信。主要使用SSL(Secure Sockets Layer, 安全套接层)和TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。格式为CONNECT 代理服务器名:端口号 HTTP版本号

HTTP响应


HTTP响应同样可分为Header和Body,它一般长这样:

HTTP/1.1 200 ok
Date: ...
Server: ..
...
空行(CR + LF)

<html>
...
</html>

第一行是状态行,包含HTTP版本、表明响应结果的状态码和原因短语。接下来是一些首部字段,一般包括响应首部字段、通用首部字段、实体首部字段和RFC里未定义的首部(Cookie等),最后是报文主体。下面重点说明一下状态码和原因短语,它们描述了本次请求的结果。

响应首部一般包含如下内容:

Date标头:消息产生的时间

Age标头:(从最初创建开始)响应持续时间

Server标头: 向客户端标明服务器程序名称和版本

ETage标头:不透明验证者

Location标头:URL备用的位置

Content-Length标头:实体的长度

Content-Tyep标头:实体的媒体类型

协商首部:Accept-Ranges: 对当前资源来讲,服务器所能够接受的范围类型Vary:首部列表,服务器会根据列表中的内容挑选出最适合的版本发送给客户端跟安全相关的响应首部:Set-Cookie:服务器端在某客户端第一次请求时发给令牌

WWW-Authentication: 质询,即要求客户提供帐号和密码

实体:位于首部行之后

实体包含了Web客户端请求的对象。Content-Length标头及Content-Type标头用于计算实体的位置、数据类型和数据长度。当Web服务器接收到Web客户端的请求报文后,对HTTP请求报文进行解析,并将Web客户端的请求的对象取出打包,通过HTTP响应报文将数据传回给Web客户端,如果出现错误则返回包含对应错误的错误代码和错误原因的HTTP响应报文。


状态码

状态码的第一位数字指定了响应类别,共可分为5类:

  • 1XX:Informational(信息性状态码),表明接受的请求正在处理。
  • 2XX:Success(成功状态码),表明请求正常处理完毕。
  • 3XX:Redirection(重定向状态码),表明需进行附加操作以完成请求。
  • 4XX:Client Error(客户端错误状态码),表明服务器无法处理请求。
  • 5XX:Server Error(服务器错误状态码),表明服务器处理请求出错。

下面列举几种常见的错误码和原因短语:

  • 200 OK:请求正常处理。
  • 204 No Content:请求正常处理,但没有资源可返回。
  • 206 Partial Content: 客户端进行了范围请求,服务器成功执行这部分GET请求。
  • 301 Moved Permanently: 永久性重定向,表明该资源已被分配了新的URI。
  • 302 Found: 临时性重定向,表明该资源暂时被分配了新的URI。
  • 303 See Other:表明请求的资源存在另一个URI,明确要求客户端采用GET方法重定向请求资源。
  • 400 Bad Request:请求报文中存在语法错误,需修改请求内容后再次发送。
  • 401 Unauthorized*:请求需包含通过HTTP认证(BASIC认证、DIGEST认证等)的认证信息,浏览器初次接收401响应会弹出认证窗口。若之前已进行过一次请求,则表示用户认证失败。
  • 403 Forbidden:请求资源的访问被服务器拒绝。服务器端没有必要给出拒绝的详细理由,不过也可以在响应主体部分对原因进行描述。未获得文件系统的访问授权(比如在IIS上部署网站时默认不能通过浏览器访问文件)、访问权限出现问题(比如从未授权的发送源IP地址试图访问)都有可能返回403响应。
  • 404 Not Found:服务器无法找到请求的资源(也可在服务器端拒绝访问且不想说明理由时使用)。
  • 500 Internal Server Error:服务器端执行请求时发生内部错误。多为服务器端程序出现Bug。
  • 503 Service Unavailable:服务器处于超负载或正在停机维护,暂时无法处理请求。

HTTP协议的一些特性

HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。这在当年都是一些小容量文本传输的情况下是可行的,但随着HTTP的普及,传输过程中包含大量图片的情况多了起来。譬如使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问该HTML页面资源的同时,也会请求该页面包含的其他资源如各种不同的图片,它们是在不同服务器上的。如果每次请求都得重新建立一次TCP连接的话,无疑会增加通信量的开销,而且频繁断开又重连会导致页面加载缓慢,影响用户体验。

持久连接(HTTP Persistent Connections)

为了解决上述问题,HTTP/1.1和一部分HTTP/1.0开始支持持久连接。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。HTTP/1.1中所有的连接默认都是持久连接。

管线化(pipelining)

持久连接使得多数请求以管线化方式发送成为可能。以往发送请求后需等待并收到响应后才能发送下一个请求,管线化技术出现后,无需等待亦可发送下一个请求。这就实现了多个请求的并行发送,提高了网络通信效率。

Cookie

HTTP是无状态协议,它不对之前发生过的请求和响应状态进行管理。无状态自然可以减少服务器的CPU及内存资源消耗,但有些时候我们又需要对过去的状态进行管理,譬如登录验证之后用户在浏览该网站其他网页时应该保持登录的状态而不是重新进行登录。当然要实现状态管理,我们可以使用很多方法,无外乎是在服务器端和客户端都保存一个凭证,之后每次请求都带上这个凭证,然后在服务器端进行比对,获取状态信息。HTTP协议中引入的Cookie技术,也是为了解决状态管理问题,采用的方法也跟我上面说的差不多,只不过这是发生在协议层面,不需要自己写很多代码管理。

具体来说,Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端状态,过程如下:

  1. 客户端第一次发送请求,请求报文中没有Cookie信息。
  2. 服务器端生成Cookie信息,在响应报文中通过Set-Cookie这个首部字段,通知客户端保存Cookie,大概长这样:

    HTTP/1.1 200 ok
    ...
    <Set-Cookie: sid=1345077140226724;path=/;expires=Fri,=>23-Oct-15 07:12:20 GMT>
    Content-Type: text/plain; charset=UTF-8

  3. 客户端再次发送请求时,自动在请求报文中加入Cookie值后发送出去。大概长这样:

    GET /image/ HTTP/1.1
    Host: github.com
    Cookie: sid=1345077140226724

  4. 服务器端收到Cookie信息后,会去检查从哪个客户端发来的连接请求,然后对比服务器上的记录,得到之前的状态信息。


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

  无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。

  HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

  从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。

  Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值