本文属于原创文章,转载请注明--桃源小盼html
做为一个程序员,当咱们访问一个接口,服务器接收到并返回结果,那么中间的流程是怎么处理的呢?这个请求是如何到达服务器,服务器又是怎样返回内容的?程序员
若是没有HTTP协议,接口请求具体实现的细节, 都须要每一个客户端和服务器各自约定和实现,而本身的规则,又不能适用于别人。这给开发带来了极大的不便,HTTP就是为此而设计的。HTTP协议用来约定双方的行为规范,让相关开发者按照相同的规则来开发网站和工具。web
HTTP协议就像发快递时填写的发货单,规定必须填写收货人,地址和手机号码,只有这样才能准确送给收货人。HTTP则是规定了如何在两台电脑间发送和接收超文本。算法
1980年,蒂姆·伯纳斯·李在CERN(欧洲核子研究组织)时,为了方便各地研究人员共享信息,提出了一个设想,"借助于超文本,链接成可互相浏览的WWW(万维网)项目"。chrome
到了1989年,伯纳斯·李看到了将超本文与互联网结合的机会,那时已经有了在电脑上显示信息的超文本系统,也有了域名系统和TCP/IP网络传输协议。伯纳斯·李又为此设计制做世界上第一个网页浏览器和网页服务器,将这一切组合起来,就能实现浏览处于世界任何地方服务器上的超文本信息。在这个过程当中,因为TCP/IP协议族中没有适合传输超文本的协议,李博士又发起了HTTP(超文本传输协议)的提议。浏览器
因而在1989年,HTTP协议诞生了。现现在最普遍使用的协议版本是在1999年制定的HTTP 1.1。缓存
`蒂姆·伯纳斯·李在2017年4月5日,得到了2016年度图灵奖,被誉为万维网之父。他发明了浏览器,
HTTP,HTML,URI等一系列相关的万维网技术。`安全
现实世界中的各行各业都有本身的行业规则,违反规则,步履艰难,而尊重规则,便如鱼得水。网络世界也须要各类各样的规则,TCP/IP协议族就是这些规则的总称。而HTTP协议是其中的一种,负责传输超文本(HyperText)。性能优化
TCP/IP协议族一共分为四层,包含不一样的协议。应用层、传输层、网络层和链路层。服务器
这张图简单描述了,打开一个网站背后都发生了什么?
经过DNS协议,得到访问域名对应的服务器IP地址。DNS协议属于应用层。
紧接着用到了HTTP协议,将生成的HTTP报文发送给服务器。HTTP协议属于应用层。
数据在网络中的传输是十分重要的,为了保证数据传输的稳定性和完整性,制定了TCP协议,它将数据分割成报文段,按序号传输。TCP协议属于传输层。
客户端发起的请求,怎么在众多机器中找到对应那一台,须要IP协议来寻找一条路径。IP协议属于网络层。
最后服务器收到了请求,把响应内容按照以前的步骤,返回给客户端。
客户端发出请求报文,服务器收到请求,通过处理,把响应报文返回客户端,链接断开,一次请求结束。HTTP协议是无状态协议。
在1990年W3C发布了第一个HTTP/0.9版本,这个版本只支持GET请求。
1996年发布了HTTP/1.0版本,这是第一个普遍使用的版本,支持了多媒体类型和各类HTTP首部字段。
但真正应用至今的是在1999年发布的HTTP/1.1版本,它修复了一些结构的缺陷,并引入了性能优化的措施。本文如下的内容都以HTTP/1.1为基础展开。
咱们用chrome浏览器打开http://www.w3c.org
这个网站。打开开发者工具的network项,看看第一个请求的详细信息。
请求报文由请求地址、请求方法、协议版本、首部字段和内容实体。
GET /index.html HTTP/1.1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) Host: w3c.org
响应报文由状态码及解释短语、协议版本、首部字段和响应实体。
HTTP/1.1 200 OK Content-Type: text/html Content-Length: 137582 Server: Apache 0.84 <html> <body>Hello World</body> </html>
HTTP/1.1 支持多种请求方法,最经常使用的仍是get和post方法。
HTTP通讯是创建在TCP链接的基础上,早期版本每次通讯都须要从新链接、断开TCP。因此在HTTP/1.1下,实现了在一次TCP链接中进行屡次HTTP通讯的能力,大大提升了服务器的响应速度。同时也支持并行发送请求,通常浏览器是支持同时6个链接。
gee方法是安全的请求方法,获取已经存在的资源或者是查询一些数据,一般会把请求参数拼接在url中。
head方法也是安全的,但它与get的不一样在于,它不会返回响应实体内容,只返回响应首部。通常会用来确认请求url的有效性。
post方法会把请求内容放在请求实体中,而不是拼接在url中。因此通常查询信息用GET方法,提交表单数据使用post方法。
查询指定url资源支持的请求方法,例如支持get和head。
通常请求发出后,会通过多层代理服务器,这个方法就是用来确认请求发出后发生的一系列操做。但会引发跨站追踪攻击,通常不用。
put是用来往服务器上传文件,而delete就是删除服务器上的文件。可是这两个方法没有验证机制,会产生不安全问题,通常服务器都不作支持。
状态码用来表示服务器返回的请求结果。由三位数字加解释短语组成,例如 200 ok。
虽然状态码有不少,可是也可分门别类,并不须要掌握全部,也对返回的结果有个大体的了解。
状态码 | 响应类别 | 缘由短语 |
---|---|---|
1xx | 信息性状态码(Informational) | 服务器正在处理请求 |
2xx | 成功状态码(Success) | 请求已正常处理完毕 |
3xx | 重定向状态码(Redirection) | 须要进行额外操做以完成请求 |
4xx | 客户端错误状态码(Client Error) | 客户端缘由致使服务器没法处理请求 |
5xx | 服务器错误状态码(Server Error) | 服务器缘由致使处理请求出错 |
当咱们知道了,首位数字是定义状态码的类型后,理解更多的状态码也就简单起来。
下面,再详细介绍一些常见的状态码。
这个是最多见的,表示请求在服务器被正确处理了。
请求在服务器端被正确处理了,可是返回的响应报文中没有实体内容。通常用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的状况。
永久性重定向,表明资源的连接已经更换了url,在响应报文中会包含新的连接地址。
当发出的请求中有附加条件(首部字段有if-*)时,服务器容许访问,可是不知足条件的状况。
请求报文内容存在语法错误,服务器处理不了。
发送的请求中含有HTTP认证信息,认证未经过。
返回401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部以质询用户信息
请求的资源拒绝被访问,通常是无权限访问。
这个也很常见,请求的资源服务器找不到。
服务器在处理请求时,出错了。通常是服务器发生了异常情况。
首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。通俗点讲,浏览器和服务器会根据这些字段作出不一样的反应,每一个字段至关于一条配置信息。
首部字段相似于键值对,请求报文和响应报文都包含首部信息。
这是一段请求首部字段,例如Accept表示浏览器能够接受的响应报文实体类型。
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4 Cache-Control:max-age=0 Connection:keep-alive Host:www.w3.org If-Modified-Since:Thu, 04 May 2017 23:40:12 GMT If-None-Match:"a384-54ebb4b41af00;89-3f26bd17a2f00-gzip"
首部字段分为了五种类型,通用首部、请求首部、响应首部、实体首部和拓展首部。
类型 | 说明 |
---|---|
通用首部 | 是请求和响应都会用到的字段 |
请求首部 | 是客户端向服务器发送请求时,报文中包含的首部字段 |
响应首部 | 是服务器向浏览器返回响应报文时,包含的首部字段 |
实体首部 | 是请求报文和响应报文中针对实体内容的首部字段 |
拓展首部 | 是非标准首部字段,由开发者根据自身需求自由定义和实现 |
如下列表,提供一些首部的简单说明,每一个字段的具体使用都不同,实际应用仍是查看详细介绍。
字段名 | 说明 |
---|---|
Cache-Control | 控制缓存行为 |
Pragma | HTTP/1.0遗留字段,也是用于控制缓存机制 |
Transfer-Encoding | 传输报文主体的编码方式 |
Trailer | 报文主体以后的首部字段,用于分块传输 |
Upgrade | 检测HTTP协议是否可用更高版本 |
Connection | 控制再也不转发给代理的字段、链接的管理 |
Date | 建立报文的日期 |
Via | 追踪客户端与服务器之间报文的传输路径,一般指代理服务器 |
Warning | 缓存相关警告 |
字段名 | 说明 |
---|---|
Accept | 客户端可接受的媒体类型及相关优先级,q值表示权重 |
Accept-Charset | 客户端可接受的字符集及优先顺序 |
Accept-Encoding | 客户端支持的内容编码及优先顺序 |
Accept-Language | 客户端可处理的天然语言集,以及优先级 |
Authorization | 客户端的认证信息,通常是证书信息 |
Host | 请求资源所在服务器的主机名和端口号 |
If-Match | 比较实体标记 |
If-Modified-Since | 比较资源更新时间 |
If-None-Match | 比较实体标记(与If-Match做用相反) |
If-Range | 资源未更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源更新时间(与If-Modified-Since做用相反) |
Max-Forwards | 最大传输逐跳数(TRACE或OPTIONS方法会用到) |
Range | 范围请求的实体字节段 |
Referer | 请求页面的原始url |
TE | 传输编码及优先级 |
User-Agent | 请求客户端的自身信息 |
字段名 | 说明 |
---|---|
Accept-Ranges | 服务器是否接受字节范围请求 |
Age | 服务器响应建立通过的时间 |
ETag | 资源配置信息 |
Location | 服务器告知客户端重定向url |
Proxy-Authorization | 代理服务器向客户端发起的认证信息 |
Retry-After | 服务器告知客户端再次请求的时间 |
Server | 服务器应用名、版本号等相关信息 |
Vary | 代理服务器的缓存管理信息 |
WWW-Authorization | 服务器对客户端的认证信息 |
字段名 | 说明 |
---|---|
Allow | 资源支持的请求方法 |
Content-Encoding | 实体内容的编码方式 |
Content-Language | 实体内容的天然语言集 |
Content-Length | 实体内容字节长度 |
Content-Location | 实体内容替代url |
Content-MD5 | 实体内容的报文摘要 |
Content-Range | 实体内容的位置范围 |
Content-Type | 实体内容对应的媒体类型 |
Expires | 实体内容失效日期 |
Last-Modified | 实体内容最后修改日期 |
HTTP协议是无状态的,若是咱们今天登陆了一个网站,明天从新打开网站时,能自动登陆,怎么办?
那就得靠cookie来解决了。它能在客户端保存用户的基本信息,当咱们下次访问该网站,浏览器会把cookie一块儿发送给服务器,服务器就会根据这些信息来判断你是否登录过。
cookie是网景公司的前雇员卢·蒙特利在1993年3月的发明的。cookie数据也是键值对的形式,它和网站以及网页是关联在一块儿的。若是保存cookie值指定了网站地址,访问其余网站时并不会发送这些cookie值。
访问一个网站,打开chrome的开发者工具,application中能够看见cookie的信息。
Expires:是用来设置cookie的绝对过时时间,默认cookie的生存周期是跟随页面的,页面关闭即失效。
Max-Age:是用来设置cookie的相对过时时间,若是同时设置了Expires值,以Max-Age为准。
path: 是用来指定与cookie绑定的网页地址,默认状况下,和该网页同一目录下的网页也能访问该cookie。
domain: 指定与该cookie绑定的域名,该域名下的网页均可以访问该cookie。
secure: 标明传输cookie值的方式。默认状况下,cookie是在不安全的HTTP连接传输,若是设定了该值,cookie将必须处于更安全的方式下才能够传输,好比接下来介绍的HTTPS。
传输:cookie在每一次的HTTP请求中都被附加发送,增长了传输流量。
安全:cookie是明文传输,有安全性问题,会被劫持和篡改。
大小:cookie有大小限制是4kb,更复杂的数据存储是没法知足的。
HTTP协议传输的数据是明文未加密的,为了安全性,网景公司设计了SSL协议(安全套接层),用SSL创建一个安全的通讯线路后,就能够在这条线路上进行普通的HTTP通讯了,与SSL组合起来就是 HTTPS了,不过如今使用更多的是TLS(安全层传输协议)。
网站使用HTTPS须要申请一个证书,由第三方的可信赖机构提供的,这是为了防止身份假装。
客户端发送协议版本,随机码,支持的加密算法和压缩方法
服务器确认使用的协议版本和加密算法,生成随机码,发送服务器证书
客户端验证服务器证书,生成48字节key,使用服务器公钥加密key,发送加密信息,客户端握手结束
服务器将两个随机码+key组合生成本次通讯密钥,用来加密信息,服务器握手结束
接下来的通讯都将在此加密通讯下进行,以上任何确认过程失败,都将断开加密通讯。
看过锤子发布会的,都知道这个组织,但具体干什么的恐怕也没几我的清楚。它是HTTPS中SSL和TLS的具体实现库。
OpenSSL是一个开放源代码的软件库包,应用程序可使用这个包来进行安全通讯,其主要库是以C语言所写成,实现了基本的加密功能,实现了SSL与TLS协议。OpenSSL能够运行在绝大多数类Unix操做系统上,OpenVMS与 Microsoft Windows。
随着互联网的发展,web页面的数据量暴增,服务多年的HTTP/1.1已经显露疲态,因为协议是固定的,因此浏览器,服务器和开发者等都经过各自的手段,来增强服务的响应能力,减缓HTTP/1.1的不足之处。
谷歌开发了SPDY这个实验性协议来提高http的性能,HTTP/2的草案就是基于SPDY3.0展开的。HTTP/2的主要目标是改进传输性能,实现低延迟和高吞吐量。升级HTTP2不会影响原有的网站应用。
HTTP/2将全部传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码。以前版本的数据传输都是纯文本的方式,二进制的解析更高效,更准确。这是整个HTTP/2性能提高的基础。
当前问题:
HTTP/1.1协议中,一个tcp链接处理一个HTTP请求。例如同时有A和B两个请求,先发送A请求,A请求响应结束,再发送B请求,若是A请求处理的时间很长,B也只能等待,这样就形成了线头堵塞。目前每一个浏览器能够同时发起6-8个tcp链接,也依然不能很好地解决大量请求的处理。就算开启了管道机制,一个tcp链接同时发送A和B请求,B仍是会等在A以后响应。
HTTP/2的方式:
HTTP/2中的请求都在一个tcp链接中处理,每一个请求和响应都被分解为独立的帧,而后并行交错发送,再在另外一端从新组装。请求之间再也不互相干扰,从而消除了没必要要的等待和延迟,巨大地提高了性能。
因为HTTP是无状态的,因此每一次请求和响应都会携带头信息,而其中不少头信息是相同的,毫无疑问增长了传输的数据量。
因此HTTP/2设计了专门用于压缩头信息的HPACK算法,在客户端和服务器端使用“首部表”来跟踪和存储以前发送的键值对,并进行更新替换。
当咱们访问一个网页时,服务器先返回HTML文档,浏览器再根据这个文档,去请求其中包含的图片,样式表和脚本。
而HTTP/2中,服务器能够对一个客户端发送多个响应,而无需客户端再多起屡次请求,客户端能够控制该功能的开启。