http是一个无状态 ,无链接的基于TCP协议的单向应用层协议css
无链接即每次连接只处理一个请求,请求和应答后就断开连接html
http的每次请求都是独立的,不相关的,协议对事物处理没有记忆功能。
HTTP无状态的特性严重阻碍了这些交互式应用程序的实现,毕竟交互是须要承前启后的,简单的购物车程序也要知道用户到底在以前选择了什么商品。因而,两种用于保持HTTP状态的技术就应运而生了,一个是Cookie,而另外一个则是Session。前端
HTTP请求报文由3部分组成(报文行+报文头+报文体):
web
Cache-Control
响应输出到客户端后,服务端经过该报文头属告诉客户端如何控制响应内容的缓存。
常见的取值有private、public、no-cache、max-age,no-store,默认为private。
private: 客户端能够缓存
public: 客户端和代理服务器均可缓存(前端的同窗,能够认为public和private是同样的)
max-age=xxx: 缓存的内容将在 xxx 秒后失效
no-cache: 须要使用对比缓存来验证缓存数据
no-store: 全部内容都不会缓存
默认为private,缓存时间为31536000秒(365天)也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。算法
ETag
一个表明响应服务端资源(如页面)版本的报文头属性,若是某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可让客户端“更智能”地处理何时要从服务端取资源,何时能够直接从缓存中返回响应。数据库
Location
咱们在JSP中让页面Redirect到一个某个A页面中,实际上是让客户端再发一个请求到A页面,这个须要Redirect到的A页面的URL,其实就是经过响应报文头的Location属性告知客户端的,以下的报文头属性,将使客户端redirect到iteye的首页中:
Location: http://www.iteye.com浏览器
Set-Cookie
服务端能够设置客户端的Cookie,其原理就是经过这个响应报文头属性实现的:
Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
更多详细见 (一个介绍http的地址)缓存
2XX 成功
200 OK,表示从客户端发来的请求在服务器端被正确处理
204 No content,表示请求成功,但响应报文不含实体的主体部分
205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,可是与 204 响应不一样在于要求请求方重置内容
206 Partial Content,进行范围请求
3XX 重定向
301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
302 found,临时性重定向,表示资源临时被分配了新的 URL
303 see other,表示资源存在着另外一个 URL,应使用 GET 方法获取资源
304 not modified,表示服务器容许访问资源,但因发生请求未知足条件的状况(缓存)
307 temporary redirect,临时重定向,和302含义相似,可是指望客户端保持请求方法不变向新的地址发出请求
4XX 客户端错误
400 bad request,请求报文存在语法错误
401 unauthorized,表示发送的请求须要有经过 HTTP 认证的认证信息
403 forbidden,表示对请求资源的访问被服务器拒绝
404 not found,表示在服务器上没有找到请求的资源
5XX 服务器错误
500 internal sever error,表示服务器端在执行请求时发生了错误
501 Not Implemented,表示服务器不支持当前请求所须要的某个功能
503 service unavailable,代表服务器暂时处于超负载或正在停机维护,没法处理请求安全
GET方法用于使用给定的URI从给定服务器中检索信息,即从指定资源中请求数据。使用GET方法的请求应该只是检索数据,而且不该对数据产生其余影响。服务器
POST方法用于将数据发送到服务器以建立或更新资源,它要求服务器确认请求中包含的内容做为由URI区分的Web资源的另外一个下属。
POST请求永远不会被缓存,且对数据长度没有限制;咱们没法从浏览器历史记录中查找到POST请求。
在规范的应用场景上说,Get 多用于无反作用,幂等的场景,例如搜索关键字。Post 多用于反作用,不幂等的场景,例如注册。
PUT方法用于将数据发送到服务器以建立或更新资源,它能够用上传的内容替换目标资源中的全部当前内容。
它会将包含的元素放在所提供的URI下,若是URI指示的是当前资源,则会被改变。若是URI未指示当前资源,则服务器可使用该URI建立资源。
DELETE方法用来删除指定的资源,它会删除URI给出的目标资源的全部当前内容。
HEAD方法与GET方法相同,但没有响应体,仅传输状态行和标题部分。这对于恢复相应头部编写的元数据很是有用,而无需传输整个内容。
OPTIONS方法用来描述了目标资源的通讯选项,会返回服务器支持预约义URL的HTTP策略。(cors预请求了解一下,阮大神系列http://www.ruanyifeng.com/blog/2016/04/cors.html)
HTTP是明文传输的,也就意味着,介于发送端、接收端中间的任意节点均可以知道大家传输的内容是什么。这些节点多是路由器、代理等。
HTTPS相对于HTTP有哪些不一样呢?其实就是在HTTP跟TCP中间加多了一层加密层TLS/SSL。
什么是TLS/SSL?
通俗的讲,TLS、SSL实际上是相似的东西,SSL是个加密协议,负责对HTTP的数据进行加密。TLS是SSL的升级版。如今提到HTTPS,加密协议基本指的是TLS。
先来了解一点概念
对称加密:
对称加密就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。
非对称加密:
有公钥私钥之分,公钥全部人均可以知道,能够将数据用公钥加密,可是将数据解密必须使用私钥解密,私钥只有分发公钥的一方才知道。
由上图可知,先进行TCP的三次握手以后,就开始TLS的三次握手,关于TLS的握手细节
见下图
发送cipher suites (支持的加密套件列表) 和 random number到服务器
发送random number, 证书(certificate),选择的cipher suite 到客户端
从证书中拿到公钥, 生成预主钥(pre master secret),用公钥加密预主钥,传输到服务端
咱们也能够来看看阮大神的爱丽丝版
开始加密通讯以前,客户端和服务器首先必须创建链接和交换参数,这个过程叫作握手(handshake)。
假定客户端叫作爱丽丝,服务器叫作鲍勃,整个握手过程能够用下图说明。
第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。
第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。
第三步,爱丽丝确认数字证书有效,而后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给鲍勃。
第四步,鲍勃使用本身的私钥,获取爱丽丝发来的随机数(即Premaster secret)。
第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。
结论: 公钥加密对称算法的私钥传到服务端,服务端用私钥解密,这个时候客户端和服务端都拥有同一个对称算法的私钥, 开始加密传输吧。
握手阶段用来创建SSL链接。若是出于某种缘由,对话中断,就须要从新握手。
这时有两种方法能够恢复原来的session:一种叫作session ID,另外一种叫作session ticket。
session ID的思想很简单,就是每一次对话都有一个编号(session ID)。若是对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就能够从新使用已有的"对话密钥",而没必要从新生成一把。
session ID是目前全部浏览器都支持的方法,可是它的缺点在于session ID每每只保留在一台服务器上。因此,若是客户端的请求发到另外一台服务器,就没法恢复对话。session ticket就是为了解决这个问题而诞生的,目前只有Firefox和Chrome浏览器支持。
仍是先来了解一点概念
又称为证书认证中心 (Certificate Authority) 中心,是一个负责发放和管理数字证书的第三方权威机构,它负责管理PKI结构下的全部用户(包括各类应用程序)的证书,把用户的公钥和用户的其余信息捆绑在一块儿,在网上验证用户的身份。CA机构的数字签名使得攻击者不能伪造和篡改证书。
CA自己有本身的证书,江湖人称“根证书”。这个“根证书”是用来证实CA的身份的,本质是一份普通的数字证书。
浏览器一般会内置大多数主流权威CA的根证书。
内容很是多,这里咱们须要关注的有几个点:
证书包含了颁发证书的机构的名字 -- CA
证书内容自己的数字签名(用CA私钥加密)
证书持有者的公钥
证书签名用到的hash算法
数字签名与摘要
简单的来讲,“摘要”就是对传输的内容,经过hash算法计算出一段固定长度的串(是否是联想到了文章摘要)。而后,在经过CA的私钥对这段摘要进行加密,加密后获得的结果就是“数字签名”。
这种状况比较简单,对证书进行检查:
证书颁发的机构是伪造的:浏览器不认识,直接认为是危险证书
证书颁发的机构是确实存在的,因而根据CA名,找到对应内置的CA根证书、CA的公钥。
用CA的公钥,对伪造的证书的摘要进行解密,发现解不了。认为是危险证书
假设代理经过某种途径,拿到XX的证书,而后将证书的公钥偷偷修改为本身的,而后喜滋滋的认为用户要上钩了。然而太单纯了:
检查证书,根据CA名,找到对应的CA根证书,以及CA的公钥。
用CA的公钥,对证书的数字签名进行解密,获得对应的证书摘要AA
根据证书签名使用的hash算法,计算出当前证书的摘要BB
对比AA跟BB,发现不一致--> 断定是危险证书
以上关于https介绍大部分来自于
https://imweb.io/topic/56d67baaca5e865230c1d4fa
http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html
在写http2.0以前先看看http1.1的一些特性
TCP连接会很慢,由于三次握手、滑动窗口、慢启动等的消耗,尽可能减小TCP连接。
长链接即TCP链接默认不关闭,能够被多个请求复用,声明Connection: keep-alive就能够了。客户端和服务器发现对方一段时间没有活动,就能够主动关闭链接 ,可是这只是解决了请求串行,并无解决并行
即在同一个TCP链接里面,客户端能够同时发送多个请求。这样就进一步改进了HTTP协议的效率。
其实HTTP管道化就是将客户端的FIFO队列移到了服务端。在客户端能够依次发送全部要发送的请求(固然这些请求是在同一个域下的),一 个请求发送完以后,没必要等待这个请求的响应被接受到,下一个请求就能够被再次发出。在服务器端维持的FIFO队列,这个队列是按照资源的重要程度排列的。 好比HTML比CSS要先返回,JS,CSS比图片先返回。
若是前面请求的响应花了很长的时间,后面的请求也仍是须要等待(被阻塞),这就是线头阻塞
因此这个方案并无实际解决同一个TCP并发请求的问题。
在HTTP1.1中,浏览器客户端能够$\color{red}{同时建立多个TCP连接,也便可以并发多个请求(注意是并发多个TCP连接,每一个TCP带一个请求)}$,可是在同一时间针对同一域名下的TCP连接有必定数量的限制(通常是6-8个TCP连接)。超过限制数目的请求会被阻塞。
为了不这个问题,只有两种方法:一是减小请求数,二是同时多开持久链接。这致使了不少的网页优化技巧,好比合并脚本和样式表、将图片嵌入CSS代码、域名分片/发散(domain sharding)等等
SPDY(读做“SPeeDY”)是Google开发的基于TCP的会话层 协议,用以最小化网络延迟,提高网络速度,优化用户的网络使用体验。SPDY并非一种用于替代HTTP的协议,而是对HTTP协议的加强。
将页面加载时间减小50%。
最大限度地减小部署的复杂性。SPDY使用TCP做为传输层,所以无需改变现有的网络设施。
避免网站开发者改动内容。 支持SPDY惟一须要变化的是客户端代理和Web服务器应用程序。
单个TCP链接支持并发的HTTP请求。
压缩报头和去掉没必要要的头部来减小当前HTTP使用的带宽。
定义一个容易实现,在服务器端高效率的协议。经过减小边缘状况、定义易解析的消息格式来减小HTTP的复杂性。
强制使用SSL,让SSL协议在现存的网络设施下有更好的安全性和兼容性。
容许服务器在须要时发起对客户端的链接并推送数据。
帧:HTTP2.0通讯的最小单位,全部帧都共享一个8字节的首部,其中包含帧的长度、类型、标志、还有一个保留位,而且至少有标识出当前帧所属的流的标识符,帧承载着特定类型的数据,如HTTP首部、负荷、等等。
消息:比帧大的通信单位,是指逻辑上的HTTP消息,好比请求、响应等。由一个或多个帧组成
流:比消息大的通信单位。是TCP链接中的一个虚拟通道,能够承载双向的消息。每一个流都有一个惟一的整数标识符
在二进制分帧层上,HTTP2.0会将全部传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装。其中,HTTP1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。
二进制分帧主要是为下文中的各类特性提供了基础。它能把一个数据划分封装为更小更便捷的数据。首先是在单连接多资源方式中,减小了服务端的连接压力,内存占用更少,连接吞吐量更大。这一点能够结合下文中的多路复用来体会。另外一方面,因为TCP连接的减小而使网络拥塞状态得以改善,同时慢启动时间的减小。使拥塞和丢包恢复的速度更快。
HTTP 2.0 中全部增强性能的核心点在于此
基于二进制分帧层,HTTP2.0能够在共享TCP连接的基础上同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息自己的语义,交错发出去,在另外一端根据流标识符和首部将他们从新组装起来。
一、能够并行交错的发送请求和响应,这些请求和响应之间互不影响
二、只使用一个连接便可并行发送多个请求和响应
三、消除没必要要的延迟,从而减小页面加载的时间
四、没必要再为绕过HTTP1.x限制而多作不少工做
五、多路复用完美的解决了线头阻塞问题。
每一个流均可以带有一个31bit的优先值:0表示最高优先级;2的31次方-1表示最低优先级。
客户端明确指定优先级,服务端能够根据这个优先级做为交互数据的依据,好比客户端优先设置为.css>.js>.jpg。服务端按此顺序返回结果更加有利于高效利用底层链接,提升用户体验。然而,在使用请求优先级时应注意服务端是否支持请求优先级,是否会引发队首阻塞问题,好比高优先级的慢响应请求会阻塞其余资源的交互。
在 HTTP 1.X 中,咱们使用文本的形式传输 header,在 header 携带 cookie 的状况下,可能每次都须要重复传输几百到几千的字节。
在 HTTP 2.0 中,使用了 HPACK 压缩格式对传输的 header 进行编码,减小了 header 的大小。并在两端维护了索引表,用于记录出现过的 header ,后面在传输过程当中就能够传输已经记录过的 header 的键名,对端收到数据后就能够经过键名找到对应的值。
在 HTTP 2.0 中,服务端能够在客户端某个请求后,主动推送其余资源。 能够想象如下状况,某些资源客户端是必定会请求的,这时就能够采起服务端 push 的技术,提早给客户端推送必要的资源,这样就能够相对减小一点延迟时间。固然在浏览器兼容的状况下你也可使用 prefetch 。