iOS好文章iOS带我飞2

HTTP知识点总结

2015-10-24  本文已影响2333人  Sheepy

最近互联网这个圈子不是很太平,继阿里缩招降薪,导致很多同学“被拥抱变化”之后,百度也宣布暂时停止社招了。于是有人疾呼“Winter is coming”,有人跟风有人反驳,一时唇枪舌剑,热闹得紧。不过身为一名技术人员,这些言论看看也就是了,市场或许真的会起变化,但也不见得是坏事,大浪淘沙,有能耐的总会留下。人常说站在风口,猪也能飞。如果风真的停了,那摔死的也就是些飞猪。像我这种,压根没站在风口也从没起飞的猪,还是脚踏实地加紧锻炼,争取更快更高更强好了。

唉扯远了,说点实在的吧。Web相关的开发人员应该都知道HTTP协议的重要性,无论是做后端还是前端,安卓还是iOS,都要跟HTTP打交道。想必用Fiddler调试Web API的时候,对返回的各种4xx、5xx状态码感到一头雾水绝不是什么愉快的体验。最近也是复习了一些相关的知识,今天就总结一下。

虽然我们有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层,分别是应用层、传输层、网络层和链路层。下面分别介绍一下各层的作用:

三次握手

我们知道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方法。

URI和URL

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

综上所述,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的时候其实表示的是一个意思。

HTTP方法

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

HTTP响应

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

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

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

状态码

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

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

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

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

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

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

HTTP协议并不算很复杂,不过涉及的内容也不少。总之,今天先这样吧。

上一篇下一篇

猜你喜欢

热点阅读