您的位置:首页 > 理论基础 > 计算机网络

HTTP协议简析

2016-05-31 18:23 633 查看

HTTP简介

  HTTP是一个无状态的面向连接的应用层协议,HTTP协议是基于TCP连接的,也就是说HTTP协议是建立在TCP的三次握手之后的,

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

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

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

  举个例子,使用Fiddler来截取对应的请求和响应:

  


  可以看出,虽然仅仅访问了一次,但锁获取的不仅仅是一个HTML而已,而是浏览器对HTML解析的过程中,如果发现需要获取的内容,会再次发起HTTP请求去服务器获取,比如图右侧中的那个common2.css。这上面19个HTTP请求,只依靠一个TCP连接就够了,这就是所谓的持久连接。也是所谓的一次HTTP请求完成。

  

HTTP请求

HTTP请求由三部分组成:

请求行

HTTP头

请求正文

1.第一部分请求行例如:

GET www.baidu.com HTTP/1.1

这个请求行由三部分组成,第一部分是请求方法,第二部分是请求网址,第三部分是协议版本。

2.第二部分HTTP头分为三种:1.请求头(request header) 2.普通头(general header) 3.实体头(entity header)

3.第三部分内容只在POST请求中存在,因为GET请求并不包含任何实体。

一个具体的post类型的HTTP请求如下图所示:



HTTP请求方法

一:HTTP请求方法

GET

对服务器资源的简单请求

HEAD

类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

POST

用于发送包含用户提交数据的请求

PUT

传输当前请求文档的一个版本

DELETE

发送一个用来删除指定文档的请求

TRACE

发送请求的一个副本,以跟踪其处理进程

OPTIONS

返回所有可用的方法;可检查服务器支持哪些方法

CONNECT

用于ssl隧道的基于代理的请求

二:常用方法GET和POST

GET方法是默认的HTTP请求方法,我们日常用GET方法来提交数据,

但是GET方法有一些缺点

(1)安全隐患,因为GET提交的数据(如账号、表头等)可以在URL中查看

(2)GET方法提交的数据是作为URL请求的一部分所以提交的数据量不能太大。

POST方法是GET方法的一个替代方法,它主要是向Web服务器提交表单数据,尤其是大批量的数据。POST方法克服了GET方法的一些缺点。通过POST方法提交表单数据时,数据不是作为URL请求的一部分而是作为标准数据传送给Web服务器,这就克服了GET方法中的信息无法保密和数据量太小的缺点。因此,出于安全的考虑以及对用户隐私的尊重,通常表单提交时采用POST方法。

Get和Post最大的区别就是Post有上面HTTP请求的第三部分——请求正文。 Get不存在这个内容。因此就像Get和Post其名称所示那样,Get用于从服务器上取内容,虽然可以通过QueryString向服务器发信息,但这违背了Get的本意,QueryString中的信息在HTTP看来仅仅是获取所取得内容的一个参数而已。而Post是由客户端向服务器端发送内容的方式。因此具有请求的第三部分——请求正文。

HTTP响应

当Web服务器收到HTTP请求后,会根据请求的信息做某些处理(这些处理可能仅仅是静态的返回页,或是包含Asp.net,PHP,Jsp等语言进行处理后返回),相应的返回一个HTTP响应。

HTTP响应在结构上很类似于HTTP请求,也是由三部分组成,分别为:

1.状态行
2.HTTP头
3.返回内容


首先阐述状态行,一个典型的HTTP状态如下:

HTTP/1.1 200 OK

第一部分是HTTP版本,第二部分是响应状态码,第三部分是状态码的描述,因此也可以把第二和第三部分看成一个部分。

状态码被分为以下五类:

信息类 (100-199)

响应成功 (200-299)

重定向类 (300-399)

客户端错误类 (400-499)

服务端错误类 (500-599)

一般常见的状态码有 :

- 200 OK 该请求被成功地完成,所请求的资源发送回客户端

- 404 Not Found 请求资源不存在或是输错了URL

- 403 Forbidden 服务器收到请求,但是拒绝提供服务

- 500 Internal Server Error 服务器发生了不可预期的错误

- 503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

接着阐述响应HTTP头

HTTP响应中包含的头包括

1.响应头(response header) 2.普通头(general header) 3.实体头(entity header)。

理论上所有的响应头信息都应该是回应请求头的。但是服务端为了效率,安全,还有其他方面的考虑,会添加相对应的响应头信息,

例,这是请求oschina首页时的响应信息:



Cache-Control:must-revalidate, no-cache, private。这个值告诉客户端,服务端不希望客户端缓存资源,在下次请求资源时,必须要重新请求服务器,不能从缓存副本中获取资源。 Cache-Control是响应头中很重要的信息,当客户端请求头中包含Cache-Control:max-age=0请求,明确表示不会缓存服务器资源时,Cache-Control作为作为回应信息,通常会返回no-cache,意思就是说,“不缓存就不缓存呗”;当客户端在请求头中没有包含Cache-Control时,服务端往往会定,不同的资源不同的缓存策略,比如说oschina在缓存图片资源的策略就是Cache-Control:max-age=86400,这个意思是,从当前时间开始,在86400秒的时间内,客户端可以直接从缓存副本中读取资源,而不需要向服务器请求。

Connection:keep-alive,这个字段作为回应客户端的Connection:keep-alive,告诉客户端服务器的tcp连接也是一个长连接,客户端可以继续使用这个tcp连接发送http请求。关于长连接的更多知识,后面我再详细讲。

Content-Encoding:gzip,告诉客户端,服务端发送的资源是采用gzip编码的,客户端看到这个信息后,应该采用gzip对资源进行解码。

Content-Type:text/html;charset=UTF-8,告诉客户端,资源文件的类型,还有字符编码,客户端通过utf-8对资源进行解码,然后对资源进行html解析。通常我们会看到有些网站是乱码的,往往就是服务器端没有返回正确的编码。

Date:Sun, 21 Sep 2014 06:18:21 GMT,这个是服务端发送资源时的服务器时间,刚开始我不知道GMT是格林尼治所在地的标准时间,以为是服务器的时间错了,还去服务器上查看过时间。http协议中发送的时间都是GMT的,这主要是解决在互联网上,不同时区在相互请求资源的时候,时间混乱问题。

Expires:Sun, 1 Jan 2000 01:00:00 GMT,这个响应头也是跟缓存有关的,告诉客户端在这个时间前,可以直接访问缓存副本,很显然这个值会存在问题,因为客户端和服务器的时间不一定会都是相同的,如果时间不同就会导致问题。所以这个响应头是没有Cache-Control:max-age=*这个响应头准确的,因为max-age=date中的date是个相对时间,不仅更好理解,也更准确。

Pragma:no-cache,这个含义与Cache-Control等同。

Server:Tengine/1.4.6,这个是服务器和相对应的版本,只是告诉客户端服务器信息,没有更多的意思。

Transfer-Encoding:chunked,这个响应头告诉客户端,服务器发送的资源的方式是分块发送的。一般分块发送的资源都是服务器动态生成的,在发送时还不知道发送资源的大小,所以采用分块发送,每一块都是独立的,独立的块都能标示自己的长度,最后一块是0长度的,当客户端读到这个0长度的块时,就可以确定资源已经传输完了。

Vary: Accept-Encoding,告诉缓存服务器,缓存压缩文件和非压缩文件两个版本,现在这个字段用处并不大,因为现在的浏览器都是支持压缩的。

第三部分HTTP响应内容就是HTTP请求所请求的信息。这个信息可以是一个HTML,也可以是一个图片。比如我访问百度,HTTP Response如图5所示。



感谢以下资料对本文提供了参考价值:

《HTTP权威指南》、《TCP/IP详解-卷1》

宋沄剑先生的博文

http://www.cnblogs.com/CareySon/archive/2012/04/27/HTTP-Protocol.html

小坦克先生的博文

http://kb.cnblogs.com/page/130970/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息