参考资料:
《Web性能权威指南》
《HTTP权威指南》
http协议全称为超文本传输协议(HTTP,HyperText Transfer Protocol),是基于tcp协议的一个应用层协议,主要定义web浏览器和web服务器之间交换数据的过程以及数据的格式。
经过不断地发展,现在http协议不仅成为了浏览器使用的通信协议,而且还成为了大部分的互联网软件和硬件应用的协议,所以在学习计算机网络时还是有必要学习http协议的。
http协议发展到现在共经历了好几个版本,这里简单了解下:
1. HTTP/0.9版本,HTTP 的 1991 原型版本称为 HTTP/0.9, 这个协议有很多严重的设计缺陷,只应该用于与老客户端的交互 ,仅支持GET方式和HTML文本传输。
2. HTTP/1.0版本,HTTP/1.0 添加了版本号、 各种 HTTP首部、 一些额外的方法, 以及对多媒体对象的处理,多种请求方式,如:GET,POST,PUT等。
3. HTTP/1.1版本,1999年公布的HTTP/1.1是目前主流的HTTP协议版本,直到现在都还在广泛使用。
4. HTTP/2.0版本,2015年HTTP/2.0正式发布,它重点关注的是性能的大幅优化,安全性更高。
虽然HTTP/2.0版本很早就发布了,但是HTTP/1.1版本目前还在大量使用。
另外,http协议具备无连接,无状态的特点,服务器无法记住客户端的身份。
在http1.0版本中,浏览器与WEB服务器的连接过程中,每次连接只处理一个请求和响应,对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接,浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应。这种连接称为短连接。
如果每次进行http请求就会进行一次tcp连接建立和断开,这显然降低了通信的性能的。后来在http1.1中改进了这个问题,使用了持久连接,持久连接的特点就是只要任意一端没有主动发起断开连接,那么则会一直保持连接状态。
http协议建立连接的过程:
首先http是一个基于tcp协议的应用层协议,客户端在和服务器进行通信前会先建立tcp连接,然后才正式开始进行http通信,通信完毕后释放tcp连接。
我们可以把客户端和服务器的通信过程分四个过程:建立连接、发送请求信息、发送响应信息、关闭连接。 一般来说http协议并不关心网络通信的细节,它把这些工作都交给了tcp协议来完成,因此在这四个过程中,我们重点关注发出请求和发出响应信息这两个过程,也就是http请求和http响应。
什么是http请求和http响应?
http请求:如果你想要向web服务器获取某些web资源时,就需要发出http请求信息向服务器请求web资源。
http响应:当服务器收到http请求后,服务器就会发送http响应信息把请求的web资源返回给客户端。
什么是web资源?
简单来说,web资源就是web服务器存储的数据,这些数据可以是文本文件,html页面,图片等其他格式的文件资源。当你发出http请求后,web服务器就会根据http请求知道你想要请求的具体类型的资源,然后把对应的资源以http响应方式发送给你。
HTTP请求格式
客户端连接上服务端后,向服务器请求某个web资源,称之为客户端向服务器发送了一个HTTP请求,HTTP的请求最常见的有两种:GET方式和POST方式,但是不管是哪一种请求方式,一个完整的请求须包括几下及部分:
一般来说,在请求头可以有多个,且请求头和请求消息中的内容都是可选的,请求头和请求消息之间要用空行进行隔开。下面通过抓包的方式来看一下HTTP请求包的格式。
HTTP响应格式
服务器收到客户端的HTTP请求后,会根据请求包中的信息把对应的web资源组装到HTTP响应包中,并返回给客户端。一个完整的HTTP响应包的内容应该包括以下几部分:
同理,在响应头中也是可以有多个,且响应头和响应消息中的内容都是可选的,响应头和响应消息之间要用空行进行隔开。下面通过抓包的方式来看一下HTTP响应包的格式。
以访问51cto网站为例,ip为59.110.244.199。
在下图中是wireshark抓取到的数据包,输入“http”把http包过滤出来,75是一个HTTP请求包。
GET方式
从http请求信息中可以看出,75这个HTTP请求包是一个GET方式的HTTP请求包,其中第一行为请求行,后面就是请求头,这个GET方式没有携带请求消息。
POST方式
下图是POST方式的HTTP请求包,第一行为请求行,第二行往下就是请求头,下面的HTML Form表单就是请求消息内容。
109是一个HTTP响应包,是针对75这个HTTP请求包进行响应的
HTTP协议对于每一个HTTP响应包都会设置一个状态码。
HTTP响应包的格式:HTTP版本号 状态码 原因叙述
举例: HTTP/1.1 200 OK
状态码用于表示服务器对请求的各种不同处理结果和状态,它是一个三位的十进制数。响应状态码分为5类:
状态码 含义
100~199 表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程
200~299 表示成功接收请求并已完成整个处理过程
300~399 为完成请求,客户需进一步细化请求。例如,请求的资源已经移动一个新地址
400~499 客户端的请求有错误
500~599 服务器端出现错误
下面是一些常用的状态码:
200(正常)
表示一切正常,返回的是正常请求结果
302/307(临时重定向)
指出被请求的文档已被临时移动到别处,此文档的新的URL在Location响应头中给出。
304(未修改)
表示客户机缓存的版本是最新的,客户机可以继续使用它,无需到服务器请求。
404(找不到)
服务器上不存在客户机所请求的资源。
500(服务器内部错误)
服务器端的程序发生错误,无法提供服务
503(服务器内部错误)
服务器暂时无法提供服务,需等待一段时间恢复
请求行格式:请求方式 资源路径 HTTP版本号
举例:GET / HTTP/1.1\r\n
请求方式主要有:GET,POST,HEAD,OPTION,DELETE,TRACE,PUT,比较常用的有GET和POST。如果没有设置,浏览器一般默认以GET方式请求,例如在浏览器中直接输入地址访问,如果要设置POST方式可通过更改表单的提交方式实现。不管是GET和POST,都是用于向服务器请求某个web资源,区别主要在于传递数据方式不一样。
这里主要介绍GET和POST两种请求方式:
GET方式,如果客户端请求方式为GET方式,那么可以在请求的URL地址后以?的形式带上交给服务器的数据,可以携带多个参数,每个参数之间以&进行分隔,例如:GET /mail/1.html?name=abc&password=xyz HTTP/1.1 ,但是GET方式也有限制,在URL地址后附带的参数的其数据容量通常不能超过1K。
POST方式,如果客户端请求方式为POST方式,说明客户端在表单内填写了内容,并提交,那么可以在请求消息内容中向服务器发送数据,且传递的数据容量没有限制。在前面我们通过wireshark软件抓到一个POST方法的http包,其实就是我们在51cto页面进行登录输入用户名和密码进行提交所发送的http包。
资源路径:请求的资源在哪个路径,上面的举例中请求的资源路径是 / 根目录。
HTTP版本号:当前请求是使用啊HTTP协议哪一个版本,上面的举例中的http请求的版本号是HTTP/1.1版本
请求头又称请求首部,是只在请求报文中有意义的首部。 用于说明是谁或什么在发送请求、 请求源自何处, 或者客户端的喜好及能力。 服务器可以根据请求首部给出的客户端信息,试着为客户端提供更好的响应,请求的首部的信息有以下一些:
Host:接收请求的服务器的主机名和端口号。
User-Agent:表示"用户代理"的意思,用于将客户端的操作系统和浏览器信息告知服务器,服务端可以根据这个字段,判断并统计终端用户的类型,一般很多安全软件可以伪造这个字段,欺骗服务器。
Referer:表示从哪个链接跳转到此页面的,包含一个URL,当我们从一个页面跳转到另外一个页面时一般会有Referer信息。
Origin:跟Referer类似,表示从哪个网站(域)跳转过来的,相比Referer,更加安全,不会携带参数包括账号密码。
Cookie:Cookie是一种客户端技术,用于记录客户端的身份信息,例如通过cookie可以登录网站。也就是说,服务器会给每个用户的数据以cokkile的形式写入每个用户的浏览器中,不同用户的cookie也是不同的,当用户通过各自的浏览器访问服务器时就会带着自己的数据,这样服务器通过cookie区分不同的用户,并把数据返回给不同的用户。
Range:用于分块请求实体内容,例如一个较大的文件,通过range多线程下载
x-forward-for:表示客户端的IP地址,一般称为“XXF”头,服务端通过这个头可以知道客户端的真实或代理IP
Accept:表示客户端能够接收哪些文件类型(MIME)
Accept-Charset:表示客户端的浏览器能够接受的字符集,常见的有UTF-8字符集
Accept-Encoding:表示客户端的浏览器能够进行解码的数据编码方式,比如gzip
Accept-Language:表示客户端的浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。 可以在浏览器中进行设置。
DNT:Chrome浏览器提供的安全功能,用于解决流量追踪问题,Do Not Track有几个取值:1代表用户不想被第三方网站追踪,0代表用户接受追踪,一般设置为1。
Set-Cookie:服务器通过此字段为客户端设置cookie信息,后续客户端根据此cookie来进行请求
Connection:表示是否需要持久连接。如果服务器看到这里的值为“Keep -Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接 )
Server:表示Web服务器信息,为了安全性,可以关闭或修改。例如:Server: nginx/1.4.6 (Ubuntu)或者Server: Apache
X-Powered-By:表示服务器的程序版本,为了安全性,可以关闭或修改
Locatioin:服务器告知客户端去哪里访问这个资源,一般用于重定向,配合状态码302使用
Refresh:服务器告知客户端,定时刷新浏览器
不管是构建请求报文还是响应报文,都可以使用通用字段,下面是一些比较重要的通用字段:
Connection:用于表示连接是否可持续,如果Connection是 keep-alive选项表示连接持续,如果是close选项则表示不持续。
Transfer-Encoding:表示输出的内容长度不能确定,需要分块处理,对于动态的内容或者在发送数据前不能判定长度的情况下,可以使用分块的方法来传送编码,比如说直播传输的数据量比较大,也不能确定数据的大小;对于静态的内容或者发送数据可以预判长度的情况下,可以使用content-length来标识
Cache-Control:用于控制缓存信息,no-cache表示防止缓存过期的网页信息,要求获取最新缓存,max-age=94608000表示服务器告诉客户端,缓存这个信息的最长时间
Via:报文经过的代理服务器信息
Data:用于表示内容产生的时间
说明:关于HTTP请求包和HTTP响应包中的请求行和响应行,请求头和响应头中的比较常用的字段已经介绍完了,另外,大家在用抓包工具抓到的http包中可能会出现一些书上没介绍过的字段,或者说不是HTTP标准中的字段,一般来说,这种字段是由浏览器厂商自行实现的。