Http协议详解

HTTP(Hypertext Transfer Protocol)就是超文本传输协议,它是现代互联网最重要也是最基本的协议。Http协议是无状态的、应用层协议,它是web开发的基础,如果想从事web方面的开发,一定要仔细学习一下这个协议。

一、Http基础

Http设计的目的就是支持客户端(一般是浏览器)和服务器端进行方便的沟通,它是一个B/S协议。因为在互联网中,一个服务器往往需要处理大量的客户端请求,Http协议应该尽可能少的占用系统资源。 为了达到这个目的,Http协议被设计成无状态的。Http协议是在TCP/IP之上的一种协议(Http属于应用层,TCP/IP属于运输层),默认端口采用的是80。

Http协议栈:
这里写图片描述

我们把Http协议中通信的两方称作ClientServer(或Host),Client向Server端经过http协议发送一个Request,Server端收到Request后经过一些列的处理返回Client一个Response,整个过程如下图所示:

这里写图片描述

我们现在用到的版本是HTTP/1.1,它比1.0版本添加了更多特性。其中比较重要的特性有:

* 支持持久连接
* 支持消息切分成块传输
* 更加丰富的cache特性
* 带宽优化及网络连接的使用
* 错误通知的管理
* 互联网地址的维护安全性及完整性

二、URL

在详细介绍Http协议之前我们先看一下URL。对于URL我想大家都已经很熟悉了,我们如果访问一个网站,我们不需要了解Http协议,我们只需要在浏览器中输入这个网站的URL即可。Web传输的核心就是请求消息,而请求消息就是通过URL进行定义的。 URL(Uniform Resource Locator) 地址用于描述一个网络上的资源,基本格式如下:

这里写图片描述

schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
  • scheme:指定低层使用的协议,一般是http,如果强调安全的话可以是http
  • host:HTTP服务器的IP地址或者域名
  • port:HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,必须指明
  • path:访问资源的路径
  • url-params:URL的参数
  • query-string:发送给http服务器的数据
  • anchor:锚

2.1 URL 的一个例子

http://www.mywebsite.com/sj/test;id=8079?name=sviergn&x=true#stuff
Schema: http
host: www.mywebsite.com
path: /sj/test
URL params: id=8079
Query String: name=sviergn&x=true
Anchor: stuffif x:
print('True')

2.2 一个URL的请求过程:

当你在浏览器输入URLhttp://www.website.com的时候,浏览器发送一个Request去获取http://www.website.com的html。服务器把Response发送回给浏览器。浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如图片,CSS文件,JS文件。
浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。当所有的文件都下载成功后, 网页就被显示出来了。

三、请求Method(Verb)

我们通过URL告诉了浏览器我们去哪个网站(主机)获得资源,而我们要在这个网站上做什么操作呢?这个具体的操作就是由请求Method定义的。当然,客户端可以对服务器做多种类型的操作,为此Http1.1协议共定义了八种标准操作:

  • GET:向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。
  • POST:向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
  • PUT:向指定资源位置上传其最新内容。
  • DELETE:请求服务器删除Request-URI所标识的资源。
  • OPTIONS:这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用’*’来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
  • HEAD:与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
  • TRACE:回显服务器收到的请求,主要用于测试或诊断。
  • CONNECT:HTTP/1.1协议中预留给能够将连接改为渠道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。

Method名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)

其中的GET、POST、PUT、DELETE这四种Method分别对应者对远程服务资源的增、删、改、查操作,而其中最长用的是GET和POST。

3.1 关于GET和POST

GET请求的数据会附在URL之后(就是据放置在HTTP协议头中),以“?”分割URL输数据,多个参数用“&”连接;例如:login.action?name=tom&password=securiy

POST会把提交的数据放置在是HTTP包的正文中。上文示例中name=Professional&id=11101就是实际的传输数据;

HTTP协议没有对传输的数据和URL长度进行限制, 但特定浏览器和服务器对URL长度有限制, 因此对于GET提交时,传输数据就会受到URL长度的限制; 由于POST操作不是通过URL传值,理论上数据长度不受限。

POST的安全性要比GET的安全性高,通过GET提交数据,用户名和密码将明文出现在URL上,容易被他人看到,URL信息也可能会被记录到历史纪录中。


GET实例:

GET /test/?id=11101&name=Professional HTTP/1.1
Host: www.test.com
User-Agent: Mozilla/5.0 (Windows; U;) Firefox/1.0.1
Connection: Keep-Alive

POST 实例:

POST / HTTP/1.1
Host: www.test.com 
User-Agent: Mozilla/5.0 (Windows; U) Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
(…… 此处空一行 ……)
name=Professional&id=11101

四、状态码Status Code

通过URL和Method,客户端就可以发送一个完整的请求给服务端。当然服务端也会做出响应。状态码就是非常重要的一种响应,客户端通过状态码就可以了解服务端做出何种响应。HTTP/1.1中定义了5类状态码, 状态码由三位数字组成,第一个数字定义了响应的类别:

  • 1XX 提示信息; 表示请求已被成功接收,告诉客户端可以继续发送下一个请求了,若如果已发送完毕可以忽略它。
  • 2XX 成功
  • 3XX 重定向; 要完成请求必须进行更进一步的处理
  • 4XX 客户端错误;请求有语法错误或请求无法实现
  • 5XX 服务器端错误;服务器未能实现合法的请求

4.1 一些常见的状态码

400 Bad Request  //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden  //服务器收到请求,但是拒绝提供服务
404 Not Found  //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable  //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

最常见的Response处理成功之后返回的状态码:

HTTP/1.1 200 OK (CRLF)

五、Http消息结构

5.1 Http消息结构概览

至此,我们已经了解到了URLVerbStatus Code相关概念,而这些信息就是组成Http消息体的主要信息,下面我们就具体看一下Http消息体的具体结构。

这里写图片描述

HTTP消息分为Request和Response两种消息,Http协议对这两种消息定义了如下结构:

message = <start-line>
      *(<message-header>)
      CRLF
      [<message-body>]

<start-line> = Request-Line | Status-Line
<message-header> = Field-Name ':' Field-Value

从上面定义我们可以看到,Http的Request和Response消息都是由三部分组成:

 1. start-line 开始行 
 2. header 消息头 
 3. body 消息体

对于start-line,又分为:

1. Request-Line : 'METHOD/path-to-resource http-version'
2. Response-Line : 'http-version status-code message'

对于Headers则有如下几种:

1. general headers
2. entity headers
3. request or response headers
    a. request specific headers.
    b. response specific headers.

下面我们再用两幅图具体看一下Request和Response的消息格式:

Request消息格式定义:
这里写图片描述

Response消息格式定义:
这里写图片描述

5.2 Http Headers

通过上面介绍我们已经Http消息的Headers共分为三种,分别是General HeadersEntity HeadersRequest/Response Headers

5.2.1 General Headers

我把被Request和Response共享的Headers成为General Headers,具体有:

general-header = Cache-Control           
               | Connection       
               | Date             
               | Pragma           
               | Trailer          
               | Transfer-Encoding
               | Upgrade          
               | Via              
               | Warning
  • Cache -Control指定请求和响应遵循的缓存机制。
  • Connection 允许客户端和服务器指定与请求/响应连接有关的选项
  • Date 提供日期和时间标志,说明报文是什么时间创建的
  • Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache
  • Trailer 如果报文采用了分块传输编码(chunked transfer encoding) 方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合
  • Transfer-Encoding 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
  • Upgrade 给出了发送端可能想要”升级”使用的新版本和协议
  • Via 显示了报文经过的中间节点(代理,网嘎un)
5.2.2 Entity Headers

EntityHeaders主要用来描述消息体(message body)的一些元信息,具体有:

entity-header  = Allow                   
               | Content-Encoding 
               | Content-Language 
               | Content-Length   
               | Content-Location 
               | Content-MD5      
               | Content-Range    
               | Content-Type     
               | Expires          
               | Last-Modified

其中,以Content为前缀的Headers主要描述了消息体的结构、大小、编码等信息,Expires描述了Entity的过期时间,Last-Modified描述了消息的最后修改时间。

5.2.3 Request/Response Headers

这部分内容放在下面的Request消息体和Response消息体中介绍。

5.3 Request消息体

通过上面介绍,我们对Request消息体结构已经有了大体了解,本节我们再深入介绍一下。

5.3.1 Request-Line

Request-Line是Request消息体的第一部分,其具体定义如下:

Request-Line = Method SP URI SP HTTP-Version CRLF
Method = "OPTIONS"
       | "HEAD"  
       | "GET"  
       | "POST"  
       | "PUT"  
       | "DELETE"  
       | "TRACE"

其中sp代码字段的分隔符,HTTP-Version一般就是"http/1.1",后面紧接着是一个换行

5.3.2 Request Headers

Request-Line后面紧跟着的就是Headers。我们在上面已经介绍了General HeadersEntity Headers,下面便是Request Headers定义:

request-header = Accept                   
               | Accept-Charset    
               | Accept-Encoding   
               | Accept-Language   
               | Authorization     
               | Expect            
               | From              
               | Host              
               | If-Match          
               | If-Modified-Since 
               | If-None-Match     
               | If-Range          
               | If-Unmodified-Since
               | Max-Forwards       
               | Proxy-Authorization
               | Range              
               | Referer            
               | TE                 
               | User-Agent

Request Headers扮演的角色其实就是一个Request消息的调节器。需要注意的是若一个headers名称不在上面列表中,则默认当做Entity Headers的字段。

前缀为Accept 的headers定义了客户端可以接受的媒介类型、语言和字符集等。From, Host, RefererUser-Agent 详细定义了客户端如何初始化Request。前缀为If 的headers规定了服务器只能返回符合这些描述的资源,若不符合, 则会返回304 Not Modified

5.3.3 Request Body

Request-Line中的MethodGET,请求中不包含消息体,若为POST,则会包含消息体。

5.3.4 一个具体的Request消息实例:
GET /articles/http-basics HTTP/1.1
Host: www.articles.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

5.4 Response消息体

Response消息格式和Request类似,也分为三部分:Response-LineResponse HeadersResponse Body

5.4.1 Response-Line

Response-Line具体定义如下:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
  • HTTP-Version字段值一般为HTTP/1.1
  • Status-Code前面已经讨论过了
  • Reason-Phrase 是对status code的具体描述

一个最常见的Response响应为:

HTTP/1.1 200 OK

5.4.2 Response Headers

下面是response-header的定义:

response-header = Accept-Ranges
                | Age
                | ETag              
                | Location          
                | Proxy-Authenticate
                | Retry-After       
                | Server            
                | Vary              
                | WWW-Authenticate
  • Age 表示消息自server生成到现在的时长,单位是秒
  • ETag 是对Entity进行MD5 hash运算的值,用来检测更改
  • Location 被重定向的URL
  • Server 服务器标识

参考资料:
http://code.tutsplus.com/tutorials/http-the-protocol-every-web-developer-must-know-part-1–net-31177
https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值