走在前端的大道上css
本篇将本身读过的相关 http/https 方法 文章中,对本身有启发的章节片断总结在这(会对原文进行删改),会不断丰富提炼总结更新。html
URI 包含 URL 和 URN,目前 WEB 只有 URL 比较流行,因此见到的基本都是 URL。前端
超文本传输协议(HTTP)是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于Web浏览器和Web服务器之间的通讯,但它也能够用于其余目的。 HTTP遵循经典的客户端-服务端模型,客户端打开一个链接以发出请求,而后等待它收到服务器端响应。 HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。java
HTTP是明文传输的,也就意味着,介于发送端、接收端中间的任意节点均可以知道大家传输的内容是什么。这些节点多是路由器、代理等。python
举个最多见的例子,用户登录。用户输入帐号,密码,采用HTTP的话,只要在代理服务器上作点手脚就能够拿到你的密码了。ios
用户登录 --> 代理服务器(作手脚)--> 实际受权服务器
在发送端对密码进行加密?没用的,虽然别人不知道你原始密码是多少 ,但可以拿到加密后的帐号密码,照样能登录。git
HTTP是应用层协议,位于HTTP协议之下是传输协议TCP。TCP负责传输,HTTP则定义了数据如何进行包装。github
简单快速、灵活、无链接、无状态web
请求报文 | 响应报文 |
---|---|
请求行 请求头 空行 请求体 | 状态行 响应头 空行 响应体 |
请求报文面试
响应报文
GET ----> 获取资源
POST ----> 传输资源
PUT ----> 更新资源
DELETE ----> 删除资源
HEAD ----> 获取报文首部
状态 | 信息 |
---|---|
1xx | 指示信息 - 表示请求已接受,继续处理 |
2xx | 成功 - 表示请求已被成功接收 |
3xx | 重定向 - 要完成请求必须进行进一步的操做 |
4xx | 客户端错误 - 请求有语法错误或请求没法实现 |
5xx | 服务器错误 - 服务器未能实现合法的请求 |
HTTPS相对于HTTP有哪些不一样呢?其实就是在HTTP跟TCP中间加多了一层加密层TLS/SSL。
通俗的讲,TLS、SSL实际上是相似的东西,SSL是个加密套件,负责对HTTP的数据进行加密。TLS是SSL的升级版。如今提到HTTPS,加密套件基本指的是TLS。
传输加密的流程
原先是应用层将数据直接给到TCP进行传输,如今改为应用层将数据给到TLS/SSL,将数据加密后,再给到TCP进行传输。
对安全或密码学基础有了解的同窗,应该知道常见的加密手段。通常来讲,加密分为对称加密、非对称加密(也叫公开密钥加密)
HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性
谷歌推行一种协议(HTTP 之下SSL之上[TCP]),能够算是HTTP2的前身,SPDY能够说是综合了HTTPS和HTTP二者优势于一体的传输协议,好比
SPDY构成图:
SPDY位于HTTP之下,TCP和SSL之上,这样能够轻松兼容老版本的HTTP协议(将HTTP1.x的内容封装成一种新的frame格式),同时可使用已有的SSL功能。
HTTP2.0能够说是SPDY的升级版(其实本来也是基于SPDY设计的),可是,HTTP2.0 跟 SPDY 仍有不一样的地方,主要是如下两点
http2 新特性
chrome=>Network=>Name栏右键=>√Protocol
本节参考文章:简单比较 http https http2、HTTPS科普扫盲帖
关于跨域,有两个误区:
✔ 跨域只存在于浏览器端,不存在于安卓/ios/Node.js/python/ java等其它环境
✔ 跨域请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了之因此会跨域,是由于受到了同源策略的限制,同源策略要求源相同才能正常进行通讯,即协议、域名、端口号都彻底一致。
可是script标签可以加载非同源的资源,不受同源策略的影响。
以下图所示:
只要浏览器检测到响应头带上了CORS,而且容许的源包括了本网站,那么就不会拦截请求响应。
CORS把请求分为两种,一种是简单请求,另外一种是须要触发预检请求,这二者是相对的,怎样才算“不简单”?只要属于下面的其中一种就不是简单请求:
(1)使用了除GET/POST/HEAD以外的请求方式,如PUT/DELETE
(2)使用了除Accept/Accept-Language/Content-Language/Last-Event-ID/Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
等几个经常使用的http头这个时候就认为须要先发个预检请求,预检请求使用OPTIONS方式去检查当前请求是否安全
代码里面只发了一个请求,但在控制台看到了两个请求,第一个是OPTIONS,服务端返回:
详见阮一峰的跨域资源共享CORS详解
JSONP是利用了script标签可以跨域,以下代码所示:
function updateList (data) { console.log(data); } $body.append(‘<script src=“http://otherdomain.com/request?callback=updateList"></script>');
代码先定义一个全局函数,而后把这个函数名经过callback参数添加到script标签的src,script的src就是须要跨域的请求,而后这个请求返回可执行的JS文本:// script响应返回的js内容为
updateList([{ name: 'hello' }]);
因为它是一个js,而且已经定义了upldateList函数,因此能正常执行,而且跨域的数据经过传参获得。这就是JSONP的原理。
跨域分为两种,一种是跨域请求,另外一种访问跨域的页面,跨域请求能够经过CORS/JSONP等方法进行访问,跨域的页面主要经过postMesssage的方式。因为跨域请求不但能发出去还能带上cookie,因此要规避跨站请求伪造攻击的风险,特别是涉及到钱的那种请求。
本节参考文章:我知道的跨域与安全
主要的过程是:
1.浏览器解析 -> 2.查询缓存 -> 3.dns查询 -> 4.创建连接 -> 5.服务器处理请求 -> 6.服务器发送响应 -> 7.客户端收到页面 -> 8.解析HTML -> 9.构建渲染树 -> 10.开始显示内容(白屏时间) -> 11.首屏内容加载完成(首屏时间) -> 12.用户可交互(DOMContentLoaded) -> 13.加载完成(load)
跳转-->应用缓存-->dns-->tcp-->request-->response
本节摘要:
当咱们在浏览器输入网址并回车后,一切从这里开始。
咱们在浏览器输入网址,其实就是要向服务器请求咱们想要的页面内容,全部浏览器首先要确认的是域名所对应的服务器在哪里。将域名解析成对应的服务器IP地址这项工做,是由DNS服务器来完成的。
客户端收到你输入的域名地址后,它首先去找本地的hosts文件,检查在该文件中是否有相应的域名、IP对应关系,若是有,则向其IP地址发送请求,若是没有,再去找DNS服务器。通常用户不多去编辑修改hosts文件。
DNS服务器层次结构
浏览器客户端向本地DNS服务器发送一个含有域名www.cnblogs.com的DNS查询报文。本地DNS服务器把查询报文转发到根DNS服务器,根DNS服务器注意到其com后缀,因而向本地DNS服务器返回comDNS服务器的IP地址。本地DNS服务器再次向comDNS服务器发送查询请求,comDNS服务器注意到其www.cnblogs.com后缀并用负责该域名的权威DNS服务器的IP地址做为回应。最后,本地DNS服务器将含有www.cnblogs.com的IP地址的响应报文发送给客户端。
从客户端到本地服务器属于递归查询,而DNS服务器之间的交互属于迭代查询。正常状况下,本地DNS服务器的缓存中已有comDNS服务器的地址,所以请求根域名服务器这一步不是必需的。
费了一顿周折终于拿到服务器IP了,下一步天然就是连接到该服务器。对于客户端与服务器的TCP连接,必然要说的就是『三次握手』。
三次握手
客户端发送一个带有SYN标志的数据包给服务端,服务端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息,最后客户端再回传一个带ACK标志的数据包,表明握手结束,链接成功。
上图也能够这么理解:
客户端:“你好,在家不,有你快递。”
服务端:“在的,送来就行。”
客户端:“好嘞。”
TCP三次握手
client----->server:SYN(发起一个TCP链接,同步报文)server----->client:SYN+ACK(应答报文,表示已建立链接)
client----->server:ACK(应答报文,表示收到已链接)
与服务器创建了链接后,就能够向服务器发起请求了。这里咱们先看下请求报文的结构(以下图):
请求报文
在浏览器中查看报文首部(以google浏览器为例):
请求行包括请求方法、URI、HTTP版本。首部字段传递重要信息,包括请求首部字段、通用首部字段和实体首部字段。咱们能够从报文中看到发出的请求的具体信息。具体每一个首部字段的做用,这里不作过多阐述。
服务器端收到请求后的由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了须要调度哪些资源文件,再经过相应的这些资源文件处理用户请求和参数,并调用数据库信息,最后将结果经过web服务器返回给浏览器客户端。
服务器处理请求
在HTTP里,有请求就会有响应,哪怕是错误信息。这里咱们一样看下响应报文的组成结构:
响应报文
在响应结果中都会有个一个HTTP状态码,好比咱们熟知的200、30一、40四、500等。经过这个状态码咱们能够知道服务器端的处理是否正常,并能了解具体的错误。
状态码由3位数字和缘由短语组成。根据首位数字,状态码能够分为五类:
状态码类别
为了不服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方均可以发起关闭请求。与建立TCP链接的3次握手相似,关闭TCP链接,须要4次握手。
上图能够这么理解:
客户端:“兄弟,我这边没数据要传了,咱关闭链接吧。”
服务端:“收到,我看看我这边有木有数据了。”
服务端:“兄弟,我这边也没数据要传你了,咱能够关闭链接了。”
客户端:“好嘞。”
由客户端发起的关闭链接
* client----->server:FIN(请求关闭链接) * server----->client:ACK(收到了链接,但不会当即关闭,等到报文都发送完再回复一个FIN) * server----->client:FIN * client----->server:ACK(收到关闭)
由服务端发起的关闭链接
* 当http设置了keepalive定时关闭,服务端会在结束数据传送后关闭TCP链接
准确地说,浏览器须要加载解析的不只仅是HTML,还包括CSS、JS。以及还要加载图片、视频等其余媒体资源。
浏览器经过解析HTML,生成DOM树,解析CSS,生成CSS规则树,而后经过DOM树和CSS规则树生成渲染树。渲染树与DOM树不一样,渲染树中并无head、display为none等没必要显示的节点。
要注意的是,浏览器的解析过程并不是是串连进行的,好比在解析CSS的同时,能够继续加载解析HTML,但在解析执行JS脚本时,会中止解析后续HTML,这就会出现阻塞问题,关于JS阻塞相关问题,这里不过多阐述,后面会单独开篇讲解。
根据渲染树布局,计算CSS样式,即每一个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:repaint和reflow。
repaint:屏幕的一部分重画,不影响总体布局,好比某个CSS的背景色变了,但元素的几何尺寸和位置不变。reflow: 意味着元件的几何尺寸变了,咱们须要从新验证并计算渲染树。是渲染树的一部分或所有发生了变化。这就是Reflow,或是Layout。
因此咱们应该尽可能减小reflow和repaint,我想这也是为何如今不多有用table布局的缘由之一。
最后浏览器绘制各个节点,将页面展现给用户。
拓展阅读:面试必考之http状态码有哪些、CDN与DNS知识汇总、前端工程师系列,TCP复习及浓缩总结(全干货,支持面试)
推荐必读:5分钟让你明白HTTP协议、分分钟让你理解HTTPS
本节参考文章:”天龙八步“细说浏览器输入URL后发生了什么
浏览器查看缓存,若是请求资源在缓存中而且新鲜,跳转到转码步骤
检验新鲜一般有两个HTTP头进行控制Expires和Cache-Control:
浏览器获取主机ip地址(DNS解析),过程以下:
打开一个socket与目标IP地址,端口创建TCP连接,三次握手以下:
浏览器接收HTTP响应,而后根据状况选择关闭TCP链接或者保留重用,关闭TCP链接的四次握手以下:
构建DOM树:
构建CSSOM树:
根据DOM树和CSSOM树构建渲染树:
从DOM树的根节点遍历全部可见节点,不可见节点包括:
发布可视节点的内容和计算样式
js解析以下:
OSI 七层涵盖:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层;
五层因特网协议栈其实就是:
五层模型就是"会话,表示,应用层"同为一层;
DNS是应用层协议,事实上他是为其余应用层协议工做的,包括不限于HTTP和SMTP以及FTP,用于将用户提供的主机名解析为ip地址。
具体过程以下:
(1)浏览器缓存: 当用户经过浏览器访问某域名时,浏览器首先会在本身的缓存中查找是否有该域名对应的IP地址(若曾经访问过该域名且没有清空缓存便存在);
(2)系统缓存: 当浏览器缓存中无域名对应IP则会自动检查用户计算机系统Hosts文件DNS缓存是否有该域名对应IP;
(3)路由器缓存: 当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客户端的DNS缓存;
(4)ISP(互联网服务提供商)DNS缓存: 当在用户客服端查找不到域名对应IP地址,则将进入ISP DNS缓存中进行查询。好比你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找;(或者向网络设置中指定的local DNS进行查询,若是在PC指定了DNS的话,若是没有设置好比DNS动态获取,则向ISP DNS发起查询请求)
(5)根域名服务器: 当以上均未完成,则进入根服务器进行查询。全球仅有13台根域名服务器,1个主根域名服务器,其他12为辅根域名服务器。根域名收到请求后会查看区域文件记录,若无则将其管辖范围内顶级域名(如.com)服务器IP告诉本地DNS服务器;
(6)顶级域名服务器: 顶级域名服务器收到请求后查看区域文件记录,若无则将其管辖范围内主域名服务器的IP地址告诉本地DNS服务器;
(7)主域名服务器: 主域名服务器接受到请求后查询本身的缓存,若是没有则进入下一级域名服务器进行查找,并重复该步骤直至找到正确记录;
(8)保存结果至缓存: 本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时将该结果反馈给客户端,客户端经过这个IP地址与web服务器创建连接。