HTTP协议的理解
1、HTTP协议相关
Web浏览器、服务器和相关的Web应用程序都是通过HTTP相互通信的。HTTP是全球因特网中使用的通用语言。
1.1 HTTP简介
超文本传输协议(HTTP)(hyper text transfer protocol)是一种为分布式的,协作的,超媒体信息系统,它是面向应用层的协议。
HTTP 的第一个版本叫做HTTP/0.9,是一种为互联网原始数据传输服务的简单协议。由 RFC 1945[6]定义的 HTTP/1.0 进一步完善了这个协议。它允许消息以类 MIME 消息的格式传送,它包括传输数据的元信息和对请求/响应语义的修饰。但是,HTTP/1.0 没有充分考虑到分层代理,缓存的,以及持久连接和虚拟主机的需求的影响。并且随着不完善的 HTTP/1.0 应用程序的激增,这就迫切需要一个新的版本,以便能使两个通信程序能够确定彼此的真实能力。此规范定义的协议叫做“HTTP/1.1”,.这个协议与 HTTP/1.0 相比,此规范更为严格,以确保各个协议的特征得到可靠实现。
下面会基于HTTP相关的具体相关介绍。
1.2 HTTP之资源
1.2.1 HTTP资源之资源类型
这里的资源就是我们平时通过浏览器等web客户端访问得到的文件:HTML文件、图片、视频等标准统一的各类格式文件。
这些各类格式的文件拥有不用的数据类型,比如我们熟知的text、image、video、application等,然后下面会继续细分。这种细分的规则称为MIME(Multipurpose Internet Mail Extension,多用途因特网邮件扩展),这个协议最早是为了解决不用的电子邮件系统之间搬移报文时存在的问题,由于它早实际应用中表现比较好,HTTP协议也接纳了它,将它作为标记要传输的多媒体内容。
下面是在HTML网页中常见的类型:
- HTML格式的文本文档:text/html
- ASCII的文本文档:text/plain
- Jepg图片:image/jepg
- Apple的Quicktime电影:video/quicktime
- 微软的PowerPoint文件:application/vnd.ms-powerpoint
这里有比较全面的介绍:MIME参考手册。
1.2.2 HTTP资源之URL
每一个资源文件都会有一个固定的名字,这样可以使它会被唯一的访问到。它们有一个统一的学名称为统一资源标识符(Uniform Resource Identifier, URI)。而我们需要了解的是它最常见的一种形式:统一资源定位符(Uniform Resource Location, URL)。这就是我们俗称的网址,它可以说明如何从一个精确固定的位置获取资源。为什么说网址都是精确固定的?因为它们的语法都建立在由9部分构成的通用格式上。如下:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
scheme: 方案,指明访问服务器需要使用的协议,如:telnet、ftp、http等。
user & password: 访问有权限的服务器可能还需要用户名和密码,如ftp。
host:访问资源所在服务器的主机名或IP地址。
port: 资源服务器监听的端口号,如http监听的80端口,telnet监听的23端口,ftp监听的22端口。
path: 资源文件所在服务器路径名称。即简单的文件路径。
params: 指明提供的参数类型,键值对形式,';'分割,用的不多。
query: '?'之后的请求参数,形式:name=daocoder&sex=fale。
frag: 片段,有点锚链接的意思,用的不多。
附上一个常见端口说明:常见端口参考。
看一个链接地址:http://www.cnblogs.com/daocoder/p/6375530.html?name=daocoder#test
基于http
协议访问host为www.cnblogs.com
下路径为daocoder/p/6375530.html
的一个文件,后面查询参数为name=daocoder,片段为test链接处。
1.3 HTTP之事务
客户端通过HTTP与Web服务器及其资源进行事务处理的过程是这样的:一个HTTP事务是由一条由客户端发往服务器端的请求命令和一个从服务器发往客户端的响应结果组成。这种通信是通过名为HTTP报文(HTTP message)的格式化数据块进行的。这里面的事务就是指发送并取得数据的整个过程。
1.3.1 HTTP事务之方法
HTTP支持几种不同的请求命令,这些命令被称为HTTP方法(HTTP method)。每个HTTP请求都会包含一个方法,这个方法会告诉服务器要执行什么动作(获取web页面、运行网关网关程序、删除文件等)。
常见方法如下:
GET: 从服务器向客户端发送命名资源。
POST: 将客户端数据发送到一个服务器网关应用程序。
PUT: 将客户端数据存储到一个命名的服务器资源中去。
DELETE: 从服务器删除命名资源。
HEAD: 仅发送命名资源响应的HTTP首部。
1.3.2 HTTP事务之状态码
每条HTTP响应报文返回时都会携带一个状态码,状态码是一个三个数字的代码,告知客户端请求是否成功或者是否采取其他动作。同时,伴随每个数字状态码,HTTP还会发送一个解释性的“原因短语”文本,这条短语是供人类观看的描述信息,所有的处理过程都是使用数字码。
基本的状态码如下:
100-199:信息性状态码
200-299: 成功状态码
300-399: 重定向状态码
400-499:客户端错误状态码
500-599: 服务器端错误状态码
状态码详细见:常见状态码说明。
1.4 HTTP之报文
在之前事务节段中说明了,HTTP客户端与服务器端的通信是通过名为HTTP报文(HTTP message)的格式化数据块进行的。这节就简要说明HTTP报文的结构。
从Web客户端发往Web服务器的HTTP报文称为请求报文(request message),从服务器发往客户端的报文称为响应报文(response message),两种报文格式很相似。
HTTP报文结构包含三个部分:
- 起始行:报文的第一行就是起始行,在请求报文中用来说明要做些什么,在响应报文中说明出现了什么情况。
- 首部字段:起始行后面后零个或多个首部字段,每个首部字段都包含一个名字和值,为了便于解析,两者之间利用":"进行分隔。首部以一个空行结束。首部字段一般又分为通用首部、请求首部、响应首部,实体首部、扩展首部。
- 主体:空行之后就是可选的报文主体了,其中包含了所有类型的数据。请求主体中包含了发送给web服务器的数据,响应主体中装载了要返回给客户端的数据。起始行和首部字段都是结构化的,主体可以包含任意的二进制数据或文本。
1.5 HTTP之连接
在了解之前的HTTP报文结构之后,就要考虑HTTP报文在互联网上的传输,即网页数据是怎么在互联网上传输的。
这里若对网络工程不是很了解的话,可以简单看看OSI七层与TCP/IP四层模型,随便找了篇博文如下:OSI七层与TCP/IP四层。想要详细学习网络相关知识的可以参见软考方面雷震甲的《网络工程师》。
1.5.1 HTTP连接之TCP/IP
HTTP是个应用层协议,它不用关心网络通信的具体细节,这些都通过通用可靠的TCP(transmission controller protocol, 传输控制协议)去完成。下面简要说明HTTP完整请求数据的步骤。
1、在客户端(浏览器)中输入url,回车访问,浏览器将不规范的url自动扩展成传输需要的规范化url。
2、浏览器通过DNS域名解析将服务器的主机名转换成服务器的IP地址。
3、浏览器将端口号从URL中解析出来,如果有的话,没有就是默认80端口。
4、浏览器与服务器建立一条TCP连接。
5、浏览器向服务器发送HTTP请求报文。
6、服务器向浏览器回送HTTP响应报文。
7、关闭连接,浏览器输出。
1.6 HTTP之Web的结构组件
之前的介绍大体是根据两种Web应用程序(web浏览器和web服务器)是如何互相发送报文实现基本事务处理来展开的。事实上,在实际互联网上还会与很多其它的web应用程序进行交互,如下。
- 代理:位于客户端与服务器之间的HTTP实体。
- 缓存:HTTP的仓库,使页面的副本可以保存在离客户端更近的地方。
- 网关:连接其他应用程序的特殊web浏览器。
- 隧道:对HTTP通信报文进行盲转发的特殊代理。
- Agent代理:发起自动HTTP请求的半智能Web客户端。
简单说上述程序的用途,某老司机通过浏览器(Agent代理)进行学习,学习的站点需要注册登录付款才能下载学习视频,老司机照做,通过HTTP连接承载加密的安全套接字层(SSL)流量(隧道),付完款后开始下载,通过HTTP请求访问HTTP/FTP网关(网关),网关通过接收下载片的HTTP请求后,利用FTP协议去获取资源,又返回承载片资源的HTTP报文,这时老司机就可以安心的学习了。然后老司机又不想自己孩子也学习这些东西,就把孩子的ip加入到了请求这个学习站点前经过的一个web服务器(代理)的黑名单中,这样老司机的孩子想要学习就回天乏术了。第二天,老司机觉得昨天的学习视频比较精髓,然后再次访问那个学习视频地址,这次浏览器从本地加载部分资源(缓存),响应速度快很多,老司机学习过程比较愉快。
2、chrome访问html页面学习解读
2.1 request header 学习解读
先打开开发者工具(Ctrl+Alt+I),转到Network选项,访问地址http://www.cnblogs.com/daocoder/p/6375530.html
。大体如下:
图片可能失效,操作如下。左侧选中点击6375530.html条目,右侧出现响应的HTTP信息界面。直接拉到最下面看Request Headers ,点击它右侧的view source,内容显示如下。
Request Headers view parsed
GET /daocoder/p/6375530.html HTTP/1.1
Host: www.cnblogs.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: CNZZDATA1000501203=2106202228-1488354446-null%7C1488354446;
If-Modified-Since: Tue, 04 Apr 2017 03:23:21 GMT
这里就是前章节提到的HTTP报文,报文又包含其它节段提到的信息,下面逐条分析。
Request Headers
说明这是请求头(1.4 HTTP之报文)。
GET /daocoder/p/6375530.html HTTP/1.1
这是起始行:请求方法GET(空格) /daocoder/p/6375530.html请求路径(空格) HTTP/1.1 HTTP协议版本
Host: www.cnblogs.com
输入的网址(host主机名)
Connection: keep-alive
保持连接状态(客户端和服务器端可中止)
Upgrade-Insecure-Requests: 1
默认http请求升级为https请求
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
浏览器用户代理人(浏览器默认,每种浏览器不同)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
这条信息以","分割去看,取倒数第三个来说,格式是这样的:application/xml;q=0.9, 前面是MIME的数据类型格式,后面q数值处0-1之间,说明偏爱系数。那么这条语句通俗来看就是说:客户端希望服务器端返回text/html或application/xhtml+xml或image/webp类型的数据,这些最容易得到;没有的话也可以是application/xml类型的数据,但喜爱程度降低10%,再没有就可以接收任意类型的数据,喜爱程度降低20%。这里面的喜爱程度到底作用多大不好说,可能与数据完整性有关。
DNT: 1
DO NOT TRACK 1代表用户不想被第三方网站追踪,0代表接受追踪,null代表用户不置可否。
Accept-Encoding: gzip, deflate, sdch
客户端希望接收数据的压缩方式。这里面的东西可以参见下面这几篇博文:GZip、deflate和sdch压缩,deflate-过时的网页压缩格式,最好禁用。
Accept-Language: zh-CN,zh;q=0.8
这里的理解方式同上,然后具体中文含义的理解可见下面知乎问题:网页头部的声明应该是用lang="zh"还是lang="zh-cn"?。
Cookie: CNZZDATA1000501203=2106202228-1488354446-null%7C1488354446;
cookie 不多说了,浏览器已保存的cookie发送过去,我删了一大截。
If-Modified-Since: Tue, 04 Apr 2017 03:23:21 GMT
缓存的一种方式,If-Modified-Since 请求头域被用来让方法成为条件方法:如果请求变量(variant)自从此头域里指定的时间之后没有改变,那么服务器不应该返回实体;而是应该以 304(没有改变)状态码进行响应,同时返回的消息不需要消息主体(message-body)。
2.2 response header 学习解读
Response Header view parsed
HTTP/1.1 200 OK
Date: Tue, 04 Apr 2017 07:03:49 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private, max-age=10
Expires: Tue, 04 Apr 2017 07:03:59 GMT
Last-Modified: Tue, 04 Apr 2017 07:03:49 GMT
X-UA-Compatible: IE=10
Content-Encoding: gzip
HTTP响应报文,报文又包含其它节段提到的信息,下面逐条分析。
HTTP/1.1 200 OK
这是起始行:HTTP/1.1 HTTP协议版本(空格) 状态码 200(空格)原因短语 ok
Date: Tue, 04 Apr 2017 07:03:49 GMT
页面响应时刻,格林威治时间,比中国晚近8小时
Content-Type: text/html; charset=utf-8
响应页面数据类型和编码
Transfer-Encoding: chunked
传输分块编码,参见下面博文:HTTP 协议中的 Transfer-Encoding。
Cache-Control: private, max-age=10
缓存控制,private指明响应消息的部分或所有部分是为一个用户准备的并且不得被共享缓存保存。可以使源服务器可以声明响应的特定部分来针对某一用户并且对其他用户的请求是无效的。一个私有(非共享)缓存可以缓存此响应。Cache-control: max-age=10 表示当访问此网页后的10秒内再次访问不会去服务器。在《HTTP权威指南》是这么说的:表示从服务器将文档传来之时,可以认为此文档处于新鲜状态的秒数。这里可以参见脚本之家的一篇文章Cache-control使用Cache-control:private学习笔记。
Expires: Tue, 04 Apr 2017 07:03:59 GMT
控制缓存生命周期,在此之前缓存有效。由于HTTP设计者认为服务器同步时钟不准确,故后来采用max-age
去计算缓存时间。
Last-Modified: Tue, 04 Apr 2017 07:03:49 GMT
变量(variant)被源服务器所确信的最后修改的日期和时间。源服务器不能发送一个迟于消息产生时间的 Last-Modified 日期。假如资源最后修改日期可能指示将来的某个时间,那么服务器应该用消息产生的时间替换那个日期。
X-UA-Compatible: IE=10
网页样式兼容IE10
Content-Encoding: gzip
响应内容压缩格式为gzip
3、写在后面
本文只是对HTTP学习的入门级片面理解,如有错误请指正,若要详细理解HTTP的内容,建议读三本书《HTTP协议(RFC2616)中文版》、《HTTP权威指南》、《TCP/IP详解卷》,欢迎交流。
网友评论