浏览器相关的前端知识

我的梦境 提交于 2020-04-01 13:11:14

一、输入url到展示页面过程发生了什么?

URL(Uniform Resource Locator)统一资源定位符,用于定位互联网上资源

 scheme://host.domain:port/path/filename 

  • scheme:定义因特网服务的类型,常见的类型有:HTTP HTTPS和GTP。
  • host:定义域主机(http默认是www)
  • domain:定义因特网域名,比如xxx.com.cn
  • port:定义主机上的端口号(http:默认是80)
  • path:定义服务器上的路径
  • filename:定义文档/资源的名称

1. DNS解析:将域名解析成IP地址

在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过IP地址,之所以我们用的是域名而不是IP,是因为IP是一段数字,特别不容易记住,而域名其实就是IP的伪装者。

什么是域名解析:DNS协议提供通过域名查找IP地址,或者是反向通过IP查找域名的服务。DNS是一个网络服务器,我们的域名解析简单来说就是DNS上记录一条信息记录。

1.1 递归查询

主机向本地域名服务器的查询一般都是采用递归查询。
所谓递归查询就是:如果主机所查询的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询的请求报文(即替该主机继续查询),而不是该主机自己进行下一步的查询,因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询所需的IP地址。

1.2 迭代查询

本地域名服务器向根域名服务器查询通常是采用迭代查询。
迭代查询的特点是这样的:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地域名服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地域名服务器进行后续的查询(而不是代替本地域名服务器进行后续的查询)。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器。让本地域名服务器再向顶级域名服务器查询。顶级域名服务器在收到本地域名服务器的查询请求后,那么给出所要查询的IP地址,要么告诉本地域名服务器下一步应当向哪一个权限域名服务器进行查询,本地域名服务器就这样进行迭代查询,最后,知道了所要解析的域名的IP地址,然后把这个结果返回给查询的主机。当然,本地域名服务器也可以采用递归查询,这取决于最初的查询请求报文的设置是要求使用哪一种查询方式。

  • 浏览器先检查自身缓存中有没有被解析过的这个域名对应的IP地址,如果有解析结束,同时域名被缓存的时间也可通过TTL属性来设置。
  • 如果浏览器缓存中没有命中(没有),浏览器会检查操作系统缓存中有没有对应的已解析的结果。而操作系统也有一个域名解析的过程,在windows中可通过C盘里面一个叫做hosts的文件来设置,如果你在这里指定一个域名对应的IP地址,那浏览器会首先使用这个IP地址。但是这种操作系统级别的域名解析过程也被很多黑客利用,通过修改你的hosts文件里的内容吧特定的域名解析到他指定的IP地址还是那个,造成所有的域名劫持。所以在window7中将hosts文件设置成了readonly,防止恶意篡改
  • 如果还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析和这个域名,这个服务器一般在你的城市的某个角落,距离不是很远,而且这台服务器的性能很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。浏览器(主机)向其本地域名服务器进行的是递归查询。
  • 本地域名服务器采用迭代查询,它先向下一个根域名服务器查询
  • 根域名服务器如果有查询的IP的值则返回,没有命中,则告诉本地域名服务器,下一次查询的顶级域名服务器的IP的值
  • 本地域名服务器向收到的顶级域名服务器进行查询
  • 顶级域名服务器如果有查询的IP地址则返回,没有命中,则告诉本地域名服务,下一次查询的权限域名服务器的IP的地址
  • 本地域名服务器向权限域名服务器进行查询
  • 权限域名服务器告诉本地域名服务器,所查询的IP地址
  • 本地域名服务器最后把查询的结果告诉浏览器(主机)。

本部分摘自:https://blog.csdn.net/qq_37288477/article/details/86582130

2. TCP连接:TCP的三次握手

3. 发送HTTP请求

请求方法:GET,POST,PUT,DELETE,HEAD,OPTIONS,TRACE,PATCH

4. 服务器处理请求并返回HTTP报文

主要讲HTTP的响应报文

包含协议版本,状态码,状态码描述

响应行:协议版本,状态码,状态码描述

响应头部:响应报文的附加信息,有名/值对组成

响应主题包含回车符,换行符,响应返回数据

5. 浏览器解析渲染页面

浏览器渲染页面一共有五个步骤

  • 根据HTML解析出DOM树
  • 根据CSS解析生成CSS规则树
  • 结合DOM树和CSS规则树,生成渲染树
  • 根据渲染树计算每一个节点的信息
  • 根据计算好的信息绘制页面

5.1 根据 HTML 解析 DOM 树

  • 根据 HTML 的内容,将标签按照结构解析成为 DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。
  • 在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。

5.2 根据 CSS 解析生成 CSS 规则树

  • 解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪。
  • 浏览器在 CSS 规则树生成之前不会进行渲染。

5.3 结合 DOM 树和 CSS 规则树,生成渲染树

  • DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树。
  • 精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度。

5.4 根据渲染树计算每一个节点的信息(布局)

  • 布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸
  • 回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

5.5 根据计算好的信息绘制页面

  • 绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上
  • 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。
  • 回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。

6. 断开连接:TCP四次挥手

二、重绘与回流

重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此 损耗较少
回流(reflow): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作:

  • 页面初次渲染
  • 浏览器窗口大小改变
  • 元素尺寸、位置、内容发生改变
  • 元素字体大小变化
  • 添加或者删除可见的 dom 元素
  • 激活 CSS 伪类(例如::link  :visited  :hover  :active)
  • 查询某些属性或调用某些方法
  • clientWidth、clientHeight、clientTop、clientLeft
  • offsetWidth、offsetHeight、offsetTop、offsetLeft
  • scrollWidth、scrollHeight、scrollTop、scrollLeft
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

回流必定触发重绘,重绘不一定触发回流。重绘的开销较小,回流的代价较高。

三、防抖与节流

防抖与节流函数是一种最常用的高频触发优化方式,能对性能有较大的帮助.

1. 防抖

  • 定义: 合并事件且不会去触发事件,当一定时间内没有触发这个事件时,才真正去触发事件。

  • 原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。

  • 场景: keydown事件上验证用户名,用户输入,只需再输入完成后做一次输入校验即可。

function debounce(fn, wait, immediate) {
    let timer = null
    return function() {
        let args = arguments
        let context = this
        if (immediate && !timer) {
            fn.apply(context, args)
        }
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
            fn.apply(context, args)
        }, wait)
    }
}

2. 节流

  • 定义: 持续触发事件时,合并一定时间内的事件,在间隔一定时间之后再真正触发事件。每间隔一段时间触发一次。

  • 原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。

  • 场景: resize改变布局时,onscroll滚动加载下面的图片时。

方法一:使用时间戳。

当触发事件的时候,我们取出当前的时间戳,然后减去之前的时间戳(最一开始值设为0),如果大于设置的时间周期,就执行函数,然后更新时间戳为当前的时间戳,如果小于,就不执行。

缺陷:第一次事件会立即执行,停止触发后没办法再激活事件。

function throttle(fn, interval) {
var previousTime = +new Date()

    return function () {
        var that = this
        var args = arguments
        var now = +new Date()
        if (now - previousTime >= interval) {
            previousTime = now
            fn.apply(that, args)
        }
   }
}

方法二:使用定时器

当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行,直到定时器执行,然后执行函数,清空定时器,这样就可以设置下个定时器。

缺陷:第一次事件会在n秒后执行,停止触发后依然会再执行一次事件。

function throttle(fn, interval) {
    var timer
    return function (){
        var that = this
        var args = arguments

   if(!timer){
        timer = setTimeout(function () {
            fn.apply(that, args)
            timer = null
         }, interval)
        }
    }
}

方法三:优化

鼠标移入能立刻执行,停止触发的时候还能再执行一次。

var throttle = function(func,delay){
    var timer = null;
    var startTime = Date.now();

    return function(){
        var curTime = Date.now();
        var remaining = delay-(curTime-startTime);
        var context = this;
        var args = arguments;

        clearTimeout(timer);
        if(remaining<=0){
            func.apply(context,args);
            startTime = Date.now();
        }else{
            timer = setTimeout(func,remaining);
        }
    }
}

本部分摘自:https://juejin.im/post/5cde77c151882526015c3d11#heading-56

四、cookies、session、sessionStorage、localStorage

浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互。

1. cookie和session

cookie和session都是用来跟踪浏览器用户身份的会话方式。

区别:

1)保持状态:cookie保存在浏览器端,session保存在服务器端

2)使用方式:

  cookie机制:如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。Cookie是服务器发给客户端的特殊信息,cookie是以文本的方式保存在客户端,每次请求时都带上它。

  session机制:当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否包含sessionid。如果有sessionid,服务器将根据该id返回对应session对象。如果客户端请求中没有sessionid,服务器会创建新的session对象,并把sessionid在本次响应中返回给客户端。通常使用cookie方式存储sessionid到客户端,在交互中浏览器按照规则将sessionid发送给服务器。如果用户禁用cookie,则要使用URL重写,可以通过response.encodeURL(url) 进行实现;API对encodeURL的结束为,当浏览器支持Cookie时,url不做任何处理;当浏览器不支持Cookie的时候,将会重写URL将SessionID拼接到访问地址后。

3)存储内容:cookie只能保存字符串类型,以文本的方式;session通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象)

4)存储的大小:cookie:单个cookie保存的数据不能超过4kb;session大小没有限制。

5)安全性:cookie:针对cookie所存在的攻击:Cookie欺骗,Cookie截获;session的安全性大于cookie。

  • sessionID存储在cookie中,若要攻破session首先要攻破cookie;
  • sessionID是要有人登录,或者启动session_start才会有,所以攻破cookie也不一定能得到sessionID;
  • 第二次启动session_start后,前一次的sessionID就是失效了,session过期后,sessionID也随之失效。
  • sessionID是加密的
  • 综上所述,攻击者必须在短时间内攻破加密的sessionID,这很难。

6)应用场景:

cookie:

  • 判断用户是否登陆过网站,以便下次登录时能够实现自动登录(或者记住密码)。如果我们删除cookie,则每次登录必须从新填写登录的相关信息。
  • 保存上次登录的时间等信息。
  • 保存上次查看的页面
  • 浏览计数

session:Session用于保存每个用户的专用信息,变量的值保存在服务器端,通过SessionID来区分不同的客户。

  • 网上商城中的购物车
  • 保存用户登录信息
  • 将某些数据放入session中,供同一用户的不同页面使用
  • 防止用户非法登录

7)缺点:

cookie

  • 大小受限(4k)
  • 用户可以操作(禁用)cookie,使功能受限
  • 安全性较低
  • 有些状态不可能保存在客户端。
  • 每次访问都要传送cookie给服务器,浪费带宽。
  • cookie数据有路径(path)的概念,可以限制cookie只属于某个路径下。

 session

  • Session保存的东西越多,就越占用服务器内存,对于用户在线人数较多的网站,服务器的内存压力会比较大。
  • 依赖于cookie(sessionID保存在cookie),如果禁用cookie,则要使用URL重写,不安全
  • 创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理,所以,过度使用session变量将会导致代码不可读而且不好维护。

JS设置cookie: document.cookie="name="+username; 

JS读取cookie:   假设cookie中存储的内容为:name=jack;password=123

//设置cookie
function setCookie(cname, cvalue, exdays) {
 var d = new Date();
 d.setTime(d.getTime() + (exdays*24*60*60*1000));
 var expires = "expires="+d.toUTCString();
 document.cookie = cname + "=" + cvalue + "; " + expires;
}

//读取
function getCookie(name){
  var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
  if(arr=document.cookie.match(reg))
    return unescape(arr[2]);
  else
    return null;
}
//删除
function delCookie(name){
  var exp = new Date();
  exp.setTime(exp.getTime() - 1);
  var cval=getCookie(name);
  if(cval!=null)
    document.cookie= name + "="+cval+";expires="+exp.toGMTString();
}

 

//创建cookie
function setCookie(name, value, expireday) {
    var exp = new Date();
    exp.setTime(exp.getTime() + expireday*24*60*60*1000); //设置cookie的期限
    document.cookie = name+"="+escape(value)+"; expires"+"="+exp.toGMTString();//创建cookie
}
//提取cookie中的值
function getCookie(name) {
    var cookieStr = document.cookie;
    if(cookieStr.length > 0) {
        var cookieArr = cookieStr.split(";"); //将cookie信息转换成数组
        for (var i=0; i<cookieArr.length; i++) {
            var cookieVal = cookieArr[i].split("="); //将每一组cookie(cookie名和值)也转换成数组
            if(cookieVal[0] == name) {
                return unescape(cookieVal[1]); //返回需要提取的cookie值
            }
        }
    }
}

 

2. sessionStorage、localStorage

HTML5中与本地存储相关的两个重要内容:Web Storage与本地数据库。其中,Web Storage存储机制是对HTML4中cookie存储机制的一个改善。由于cookie存储机制有很多缺点,HTML5不再使用它,转而使用改良后的Web Storage存储机制。本地数据库是HTML5中新增的一个功能,使用它可以在客户端本地建立一个数据库,原本必须保存在服务器端数据库中的内容现在可以直接保存在客户端本地了,这大大减轻了服务器端的负担,同时也加快了访问数据的速度。

sessionStorage:将数据保存在session对象中。所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据。

localStorage:将数据保存在客户端本地的硬件设备(通常指硬盘,也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问网站时仍然可以继续使用。

这两者的区别在于,sessionStorage为临时保存,而localStorage为永久保存。

到目前为止,Firefox3.6以上、Chrome6以上、Safari 5以上、Pera10.50以上、IE8以上版本的浏览器支持sessionStorage与localStorage的使用。

WebStorage的目的是克服由cookie所带来的一些限制,当数据需要被严格控制在客户端时,不需要持续的将数据发回服务器。

WebStorage两个主要目标:①提供一种在cookie之外存储会话数据的路径。②提供一种存储大量可以跨会话存在的数据的机制。

HTML5的WebStorage提供了两种API:localStorage(本地存储)和sessionStorage(会话存储)。

1)生命周期:

localStorage:localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。

sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。

2)存储大小:localStorage和sessionStorage的存储数据大小一般都是:5MB

3)存储位置:localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信。

4)   存储内容类型:localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理

5)   获取方式:localStorage:window.localStorage;;sessionStorage:window.sessionStorage;。

6)   应用场景:localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据。sessionStorage:敏感账号一次性登录;

WebStorage的优点:

1)存储空间更大:cookie为4KB,而WebStorage是5MB;

2)节省网络流量:WebStorage不会传送到服务器,存储在本地的数据可以直接获取,也不会像cookie一样美词请求都会传送到服务器,所以减少了客户端和服务器端的交互,节省了网络流量;

3)对于那种只需要在用户浏览一组页面期间保存而关闭浏览器后就可以丢弃的数据,sessionStorage会非常方便;

4)快速显示:有的数据存储在WebStorage上,再加上浏览器本身的缓存。获取数据时可以从本地获取会比从服务器端获取快得多,所以速度更快;

5)安全性:WebStorage不会随着HTTP header发送到服务器端,所以安全性相对于cookie来说比较高一些,不会担心截获,但是仍然存在伪造问题;

6)WebStorage提供了一些方法,数据操作比cookie方便;

    setItem (key, value) ——  保存数据,以键值对的方式储存信息。

         getItem (key) ——  获取数据,将键值传入,即可获取到对应的value值。

          removeItem (key) ——  删除单个数据,根据键值移除对应的信息。

          clear () ——  删除所有的数据

          key (index) —— 获取某个索引的key

五、浏览器内核

浏览器内核是什么?英文叫做:Rendering Engine,顾名思义,就是用来渲染网页内容的,将开发者写的代码转换为用户可以看见的完美页面。由于牵扯到排版问题,所以肯定会排版错位等问题。为什么会排版错位呢?有的是由于网站本身编写不规范,有的是由于浏览器本身的渲染不标准。现在有几个主流的排版引擎,因为这些排版引擎都有其代表的浏览器,所以常常会把排版引擎的名称和浏览器的名称混用,比如常的说IE内核、Chrome内核。其实这样子是不太合理的,因为一个完整的浏览器不会只有一的排版引擎,还有自己的界面框架和其它的功能相辅相成的,而排版引擎本身也不可能实现浏览器的所有功能。

(1)Trident内核,由于被微软采用,并得益于微软操作系统的普及,以前几乎一统天下,所以又称为“IE内核”,主要浏览器有IE系列浏览器;

(2)Gecko内核,因为被Mozilla FireFox浏览器采用并得到开发者的进一步丰富,又被称为“Firefox内核”;

(3)WebKit内核,是Safari浏览器使用的内核,由Apple研发。 Google Chrome、Opera及各种国产浏览器高速模式也使用Webkit作为内核。

(4)Blink内核,由Google和Opera Software共同开发的浏览器内核,现在Chrome(28及往后版本)、Opera(15及往后版本)都将Webkit内核换成了Blink内核。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!