HTTP|HTTP是什么?是怎么发展的?

首先我们来了解一下什么是HTTP协议
HTTP:HyperText Transfer Protocol,中文超文本传输协议;
顾名思义,主要就是用于传输超文本的,相当于一条海上运输的贼船。
超文本:指的是带有超级链接的文本,相当于这条贼船运输的特殊货物,这些货物是什么呢,是任意门。
超链接:基于此种链接能够在文档间实现跳转,也就是能通向其他空间的任意门。

 HTTP|HTTP是什么?是怎么发展的?
文章图片
http/0.9
在当时,http协议广泛应用的版本为0.9,那个时候的Web服务仅支持纯文本(纯文本:由纯ASCII字符组成的文本),这种纯文本还包括超链接,这种超链接也是表现为纯文本形式的,但这种文本比较独特,因此称为超文本(HTML)。

 HTTP|HTTP是什么?是怎么发展的?
文章图片
HTML:HyperText Mark Language,超文本标记语言;这是用于编写(开发)超文本的语言
之所以叫标记语言是因为在这种语言当中事先规定好了将语言通过标签的形式给它加上一些特殊的标记,而这些文本在被用户客户端浏览器解析时能够将这些标记解析为字体格式或一些表现属性,如:Title。通俗的比喻,HTML是暗号,每个暗号都有一段特殊含义,例如:某些交易行业有一些暗语,“‘空’是有空的意思,‘路’是在路上,‘见’是见到了客人,‘喜’是被客人看上了,‘收’是完成交易收款,‘回’是返回。”

 HTTP|HTTP是什么?是怎么发展的?
文章图片
Browser:浏览器,客户端代理的一种,通过http协议可以访问服务器端提供的超文本,而Browser能够在这些文本显示的时候将标签解析为对应的修饰的属性格式。相当于暗语翻译机。
当Web服务流行开来之后,全球能够提供Web服务的服务器有很多个,那么每一台服务器上都可以提供各种各样的文本,甚至于两台服务器上提供的文本的名字可能是一样的。就好像流行给每个人取名字以后,大家都会争相给娃取名字,于是像张杰、张伟这样的名字遍布全国各地,那么如果要去民政局登记结婚,怎么区分是山东的张伟和李小姐结婚了还是湖北的张伟呢?

 HTTP|HTTP是什么?是怎么发展的?
文章图片
因此仅靠文件名进行区分文档是不可靠的。于是就出现了向URI这样的机制(虽然URI并不是专门为Web诞生的),URI是很好的能够让客户端识别互联网上不同文档的机制。
URI:Uniform Resource Indientifier,统一资源标识符;
用于定义全局范围内标记唯一的定位一种资源访问路径的方式(命名方式);(不一定是互联网上的,全球的,包括互联网在内的可以在全局唯一引用某一个独立的资源的命名方式)
统一资源标志符URI就是在某一规则下能把一个资源独一无二地标识出来。还是用取名字做例子,假设这个世界上所有人的名字都不能重复,那么名字就是URI的一个实例,通过名字这个字符串就可以标识出唯一的一个人。现实当中名字当然是会重复的,所以身份证号才是URI,通过身份证号能让我们能且仅能确定一个人。
URL:Uniform Resource Locator,统一资源定位符(URI的子对象、子集)
用于描述在互联网上互联网资源的统一表示格式。
也拿人做例子然后跟HTTP的URL做类比,就可以有:人物住址协议://地球/中国/湖北省/武汉市/洪山区/某道路/某楼栋/403号办公室/张伟.人可以看到,这个字符串同样标识出了唯一的一个人,起到了URI的作用,所以URL是URI的子集。URL是以描述人的位置来唯一确定一个人的。在上文我们用身份证号也可以唯一确定一个人。对于这个在武汉的张伟,我们也可以用身份证号:123456789来标识他。所以不论是用定位的方式还是用编号的方式,我们都可以唯一确定一个人,都是URl的一种实现,而URL就是用定位的方式实现的URI。
回到Web上,假设所有的Html文档都有唯一的编号,记作html:xxxxx,xxxxx是一串数字,即Html文档的身份证号码,这个能唯一标识一个Html文档,那么这个号码就是一个URI。而URL则通过描述是哪个主机上哪个路径上的文件来唯一确定一个资源,也就是定位的方式来实现的URI。
格式:protocol://HOST:port/path/to/file
HTTP方法:(获取资源的方式)
http/0.9时只有一个方法:
GET,它表示直接从服务器上获取文档到本地浏览器并予以展示(不是简单的文件传输,而是超文本的文件传输);
【 HTTP|HTTP是什么?是怎么发展的?】在http升级到1.0之后有了更多的方法:
PUT:从远程服务器上直接获取文件到本地,与POST相对应
POST:与GET相对应,通过表单提交数据到服务器上去;
DELETE:在远程服务器上删除文件,与PUT相对应;
HEAD:只返回首部,不响应主体;
简单来说,get是七八十年代实打实的通过相亲方式认识接触的女朋友;而科技发展了以后我们有了手机,put是从聊天软件诸如momo、tantan这样的应用里撩到的女朋友;有了女朋友你得给她花钱了吧,所以post是陪女朋友逛街给她买单;delete就是在聊天软件上你和“女朋友”聊的不爽了要分手,你就把她删除拉黑了。分页标题

 HTTP|HTTP是什么?是怎么发展的?
文章图片
对于服务器来讲,PUT、POST、DELETE都不安全,因为它们都允许客户端直接操作服务器上的资源,因此一般来讲,需要通过认证以后才能允许客户端操作。最安全的方法就是GET,GET类似于只读的意思。
MIME机制:
HTTP1.0更大的改进之处就是引入了MIME机制:
MIME:Multipurpose Internet Mail Extension,多功能(用途)互联网扩展邮件;
MIME实现了能够将非文本(如:二进制)数据在传输前重新编码为文本格式再进行传输,接收方能够用相反的方式将其重新还原成原来的格式,还能够调用相应的程序打开此文件。如:传输过去一个rar文件,对方知道这是一个rar压缩包并且能够用相应的软件打开;若传输的是图片就能调用程序打开图片。所以在MIME编码当中,Base64就是一种文本编码格式。
SMTP:Simple Mail Transfer Protocol,简单邮件传输协议;
邮件传输协议早期只能传输纯文本,但后来不仅可以传输纯文本,还可以传输图片、视频等二进制文件,因为后来引入了MIME机制。
在http1.0协议当中,也是纯文本传输的,后来参照了SMTP的纯文本传输机制将MIME引入到了http协议当中,从此以后,http协议也可以传输非文本数据了。
实现过程:在客户端去获取某个资源时,资源传递到客户端时,明确说明是哪一类文件,如:是一个image/jpeg格式的图片,通过http协议的元数据(协议首部),在协议首部里边明确添加一个首部,告诉对方自己的文件是image/jpeg格式,所以客户端发现这是一个image大类下的jpeg小子类。此时,浏览器调用内部与之相匹配的插件来展示这个文件。若浏览器不支持这种插件,可以通过接口调用外部的系统上安装的其它的能够显示文件的插件,以插件的机制在浏览器中去解析对应MIME格式的文档的。因此我们可以发现若未安装flash插件,打开网页后许多flash插件是无法显示的也正是基于此种原理。当然,也正是这种插件机制的实现,使得后来出现了动态网页的技术。
动态效果:
如:Java,Applet,JRE。嵌入到网页中,通过http协议传输到客户端,通过JRE环境展示动态效果,但由于过于重量级,在与flash的竞争中落败。
动态网页:
动态网页指的就是在服务器端存储的用户访问的文档不再是HTML格式,而是编程语言开发的脚本(也可以是非脚本)。这个脚本在接收参数之后在服务器运行一次,运行完成之后会生成HTML格式的文档,并且把生成的文档发送给客户端。需要注意的是,这个编程语言所开发的脚本在用户访问时不是原封不动的发送给客户端,而是要先获取客户端的特性(客户端获取资源时需要先发起申请,而在发起申请之前需要把客户端地址、客户端浏览器的类型等一并发送给服务器),服务器获取客户端地址,浏览器类型等数据并将这些数据当做参数传递给脚本,让脚本在服务器端执行一次。因此任何一个用户去访问,都是根据用户的特性随时生成的,所以称为动态网页。
http请求在服务器端处理的过程详细描述:(请求分别为静态网页与动态网页时的情况)

 HTTP|HTTP是什么?是怎么发展的?
文章图片
首先我们需要确定的是Web服务器是一个进程,这个进程在用户空间(Web服务器是一个特殊的具体应用,而既然是具体应用那就是一个具体的软件,那么这个软件就应该放在用户空间)。而用户所有能够访问的网页文件都存放在磁盘上,因此客户端向服务器发起请求时,这个请求先到达内核空间,而又因为这个客户端请求一定是通过网络协议发送过来的,而协议工作在内核(TCP/IP协议在内核工作),所以首先到达内核,内核空间解析接收到请求后,在内核中通过TCP/IP协议栈中各种路由机制(编码)等发现这个请求访问的是本机地址80端口的套接字,因为Web服务一旦启动之后一定会监听在TCP协议的80端口之上,因此内核就将请求通过套接字转交给用户空间的Web服务器,因此执行流程就从内核空间转到了用户空间了。
若Web服务器发现用户访问的是一个文件,如:index.html,此时服务器就得陷入到内核中,重新转换为内核模式,到磁盘上将文件加载过来,内核找到这个文件后再返回给用户空间,此时又回到了Web服务器了,Web服务器发现这个文件取出来了就可以响应客户端了。此时再通过套接字回到内核空间,通过网络TCP/IP协议栈最终响应给客户端。
如果用户访问的是动态网页,就不能直接予以响应了,需要通过其它协议启动另外一个进程,这个进程一定是一个解释器,如bash脚本就是bash解释器,PHP脚本就是PHP解释器。然后通过协议将这个文件传递给这个解释器或者这个解释器能够访问这个文档解释器自己陷入到内核模式将文档读取到解释器中,在解释其中执行一次,将执行结果返回给Web服务器。
Web服务器将请求的结果通过网络传递给客户端,它需要额外启动一个进程,进程和服务器之间建立的联系是通过协议实现的,而在这个进程执行结束后需要销毁。所以对于Web服务器来讲,若要响应一个动态内容,需要先创建一个新的子进程,这个进程执行一次结束后需要将这个进程销毁,而这都是系统资源开销,对于一个客户端访问可能无所谓,但成千上万的客户端访问呢?因此我们可以推断到响应动态内容服务器需要更多的系统资源。分页标题
在一个HTML网页中,可能会通过超链接引用n个资源(Web对象),而这n个web对象每一个都有自己的URL。而动态网页生成的HTML结果中也可以引用web对象,这些web对象是静态的,所以动态网页包含:静态内容(无需改变或无需执行的内容如:图片、文件、rar压缩包)和动态内容(需要执行一次才能返回给客户端,只有动态内容才需要运行)。在http1.0之后就能支持这些机制了,正是1.0中引入了MIME,使得Web服务对于多媒体的支持得到了极大的扩展,也正是1.0系列的出现,使得web服务器迅速流行开来并大大的促进了互联网的发展。
我们再来详细讨论一下整个过程:
以纯静态页面来讲,所有用户访问的内容都是一样的,由此我们来分析一个问题:
一个客户端发起Web服务请求到服务器需要经过多少个层次呢?如在浏览器输入一个url访问,第一步需要把FQDN转换成IP地址,因此在请求发出之前需要先通过DNS服务器解析FQDN,而DNS服务器可能会递归、迭代,需要消耗一些时间(在第一次访问时,记录未缓存到本地),之后客户端输入地址发送请求给服务器,服务器接收请求后,在内部需要有一个机制能够接收用户的请求,这种机制就叫做监听,监听在某个端口上,等待客户端的请求。
一旦用户请求来了,而内核通过TCP/IP协议栈发现有人监听在这个端口上,于是这个请求就可以交给这个套接字了。但如果本地没有任何一个用户进程监听在某个套接字,但有客户端来访问了,此时内核无法知道有谁能够响应这个请求,此时就会拒绝客户端请求,如:此地未启动这个服务,因此必须到内核中去注册需要使用哪一个端口并一直在这个端口上处于等待状态。所以当有请求到来时,通过TCP/IP协议的首部解码后发现用户访问的是这么一个端口,于是就把这个请求转交给这个端口,而进程又一直监听在这个端口,一旦有请求来了,可进行响应。
http报文:
TCP/IP协议在封装报文时,TCP首部主要是源端口(Source Port)、目标端口(Destination Port),IP首部主要是源IP地址(Source IP)、目标IP地址(Destination IP)。但却并没有明确说明具体访问哪个文档或资源,因此某一特定的应用在通过TCP/IP协议往外发送时,TCP/IP最多就是将报文传递到目的地,到达目的地后还需要具体协议的报文首部。因此http协议也有自己的首部,叫http首部,它明确定义了基于哪种协议获取哪个资源的,需要说明获取什么文档,
如:GET /2.html,并且还需要说明获取哪个主机的资源,因此通常还有一个首部叫:Host 加主机是HTTP1.0中引入的一种机制,在发起获取资源请求时,不但要指明获取哪个资源,还要再加上获取哪个主机的资源,这个主机一定是主机名称,这是为虚拟主机做准备的)。说白了,这一切就叫http报文。
IP:
Source IP
Destination IP
TCP:
Source Port
Destination Port
http首部:
GET/2.html
http报文分为两种:请求报文、响应报文。
报文语法:

 HTTP|HTTP是什么?是怎么发展的?
文章图片
上面两个报文的第一行称为报文"起始行(start line)";后面的标签格式的内容称作首部域(Header field),每个首部域都由名称(name)和值(value),中间用逗号分隔,另外,响应报文通常还有一个称作Body的信息主体,即响应给客户端的内容。
请求报文:
method:资源获取方法;
request-URL:请求的资源是什么;
version:对应请求资源协议的版本号;
headers:http协议首部;
headers后的空白行是必须的;
entity-body:空白行后有一些报文主体(报文内容)
响应报文:
version:对应请求的版本
status:状态(代)码,请求结果正确与否的标识符
状态码分为5类:
1xx:纯信息,与请求的资源没有太大的关系;
2xx:“成功”类的状态码信息,常用状态码:200(表示请求资源正常,已获取到正常响应);
3xx:重定向类的信息,表示请求的资源已存在,但资源已被挪到其它地方了,如:给了一个参考答案说这个资源已经被挪走了,请重新发起请求另外一个地址,并且把另外的参考地址也响应给客户端了。常用的状态码:301(表示永久重定向,永久的挪到了那个位置了)、302(临时重定向,繁忙时重定向到指定位置寻找)、304(表示请求的内容未发生任何改变,若缓存过直接使用缓存即可)。需要注意的是,重定向的信息未必都是重定向,如304状态码;
4xx:客户端错误类信息,常用状态码:404(请求了一个不存在的文件);
5xx:服务器端错误类信息;
reason-phrase:定义解释status的意义;
headers:响应报文首部;
entity-body:报文主体;
报文举例:

 HTTP|HTTP是什么?是怎么发展的?
文章图片
GET/HTTP/1.1中的/表示访问一个网站但没有明确指定访问哪个页面,/表示访问对方的默认页面(主页)。
缓存:在http/1.0中,引入缓存的机制时为了加速系统访问、节省网络带宽的。分页标题
http协议基于TCP协议,每一个TCP的建立都需要3次握手,而拿到资源后需要4次断开。为了避免每一次访问资源都要三次握手、四次挥手,推出了http/1.1。
http/1.1:
增强了缓存功能;
引入了长连接;
获取资源后并不是立即断开连接,而是继续获取下一个资源;而长连接可以让同一个客户端发起第二个请求时尽可能缩短时间也降低服务器端资源占用率,但是当服务器端带宽占用巨大时,后来的客户端可能很难建立连接了。
因此,为了资源的有效利用不能让建立长连接的客户端永久在线,因此给出两个限定:1.若请求第一或第二个资源后就不再请求,需要定义一个超时时间,到达一定时间后超时断开;2.当一直请求不断开时,定义做多请求多少次,如还请求,需要重新排队。

 HTTP|HTTP是什么?是怎么发展的?
文章图片