前端面试5-浏览器

目录

1、跨域问题

2、浏览器从输入URL到渲染页面的过程

3、session、cookie、sessionStorage、localStorage

1、跨域问题

        跨域是由于浏览器的同源策略造成的,是浏览器施加的安全策略

        同源策略(SOP):拥有相同的协议、域名、端口号的网址间才可以相互访问资源

        跨域并不是请求发不出去,而是请求发出去了,也正常返回结果了,但结果被浏览器拦截了

        常用的解决方案:JSONP、CROS、代理服务器

                1)JSONP只接受GET请求

                带有src属性的标签不受浏览器同源策略的影响,可以通过src属性请求非同源js脚本

                2)CORS 设置响应头

                        response.setHeader('Access-Control-Allow-Origin','*')

                        默认情况在跨域请求,浏览器是不携带cookie的,但可以通过设置withCredentials来进行传递cookie');

//原生xml的设置方式
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
//axios设置方式
axios.defaults.withCredentials = true;
CORS和JSONP对比

CORS与JSONP相比,无疑更为先进、方便和可靠。

(1)JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求;

(2)使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理;

(3)JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS;

        3)HTML5的window.postMessage方法跨域

                为了解决跨域问题,HTML5引入一个全新的API:跨文档通信API(Cross-document messaging);这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。

        如:父窗口http://a.com向子窗口http://b.com发消息。

        a页面

<iframe id="frame1" src="http://127.0.0.1/JSONP/b.html" frameborder="1"></iframe>
document.getElementById('frame1').onload = function(){
    var win = document.getElementById('frame1').contentWindow;
    win.postMessage("我是来自a页面的","http://127.0.0.1/JSONP/b.html")
}

        b页面

window.onmessage = function(e){
    e = e || event;
    console.log(e.data);//我是来自a页面的
}

 

2、浏览器从输入URL到渲染页面的过程

        1)URL解析:判断用户输入的是否是合法的URL(统一资源定位);如果不是则搜索引擎搜索,如果符合url规则则会根据url协议合成合法的url;

        2)查找缓存:网络进程获取到url,先去本地缓存中查找是否有缓存资源,如果有则拦截请求,直接将缓存资源返回给浏览器,否则进入网络请求阶段;

        3)DNS域名解析:DNS协议通过域名查找IP地址或是逆向地从IP地址查找域名的服务。DNS是一个网络服务器,上面存放了各个域名和其IP地址之间的关系数据;

                DNS查找数据缓存服务中是否缓存过当前域名信息,有则直接返回,否则进行DNS解析返回域名对应的IP和端口号,没有指定端口号时,http默认为80端口,https默认为443端口;如果是https请求,还需要建立TLS连接;

        4)TCP连接:

                TCP三次握手与服务器建立连接,然后进行数据的传输;

                发送HTTP请求,包含请求行、请求头、请求体;

                服务器处理请求,返回响应行、响应头、响应体;

        5)页面渲染:

                ①解析HTML的所有标签,深度遍历生成DOM树;

                ②解析CSS,构建层叠样式表模型(CSSOM);

                ②.₅JS脚本加载

                        

                        a.普通JS/sync:文档解析过程中,如果遇到script脚本,就会停止页面的解析进行下载,当脚本都执行完毕后,才会继续解析页面;如果脚本是外部的会等待脚本下载完毕再继续解析文档;(因为JS脚本中可能会改动DOM和CSS继续解析会造成浪费) 

                        b.async:async脚本会在加载完毕之后执行;async脚本的加载不计入DOMContentLoaded事件统计

                                第一种:HTML还没有被解析完时,async脚本已经加载完毕,则HTML停止解析,执行脚本,脚本执行完毕后触发DOMContentLoaded事件

                

                                 第二种:HTML解析完后,async脚本才加载完毕,HTML解析完毕就触发DOMContentLoaded事件

                        c.defer:文档解析时遇到设置defer的脚本,就会再后台进行下载,但并不会阻止文档的渲染,当页面解析和渲染完毕后,等所有defer脚本加载并执行完毕后才会触发DOMContentLoaded事件

                                第一种:HTML还未解析完时,defer脚本加载完毕,等待HTML解析完后再执行脚本,脚本执行完毕后触发DOMContenLoaded事件

                                第二种:HTML解析完毕时,defer脚本还未加载完毕,等待defer加载和执行完毕后才触发DOMContentLoaded事件

                ③构建渲染树(Render Tree)DOM树和CSSOM根据一定的规则组合起来生成了渲染树;

                ④布局:根据渲染树确定各个元素的位置及大小;浏览器使用一种流式处理的方法,只需要一次绘制操作就可以布局所有元素;

                ⑤绘制:浏览器会遍历Render Tree,调用paint方法,将渲染树的各个节点绘制到屏幕上

                    重绘:外观发生改变,但没有改变布局;

                             因元素的颜色、字体等不改变尺寸和位置的样式改变而重新绘制,性能消耗较小

                     重排(回流):元素改变尺寸、宽高、边框、内容、位置等,导致需要重新构建页面

                                页面第一次渲染;增删可见DOM元素;元素尺寸、内容发生改变;

        6)断开TCP连接:数据传输完成,正常情况下TCP四次挥手断开连接

3、session、cookie、sessionStorage、localStorage

         cookie和session都是参与服务器通信的,而localStorage和sessionStorage不参与服务器通信;

        3.1cookie和session

                cookie和session是常用的会话跟踪技术;cookie通过在客户端记录信息确定用户身份,session通过服务器端记录信息确定用户身份;session较cookie更安全;

                cookie的作用是在客户端保持状态,比如登陆状态。在发送http请求时会被放进请求头中参与通信。每个cookie最大为4k,每个域名可以拥有的cookie数量在不同浏览器中是不同的,但都多于20个,早期的20个限制已经不存在;

                session的作用是在服务器端保持状态。session被创建的时候会生成一个sessionid,它被存储在cookie中用来访问session;由于关闭浏览器不会导致session被删,迫使服务器为session设置了失效时间;

        3.2session和sessionStorage

                session存储于服务器(后端);sessionStorage存储于客户端;

                session对于服务器(后端)来说是一个标识;sessionStorage堆客户端(前端)来说是存储的功能

                session存储维持会话状态的key,sessionStorage存储会话期间的数据;(浏览器的window对象中的sessionStorage中存贮着后台的session)

        3.3localStorage和sessionStorage

                浏览器本地存储分为:cookie,webStorage和IndexDB

                localStorage和sessionStorage都属于webStorage本地存储,不参与服务器通信,都属于window对象,最大存储都在5M左右

                localStorage是永久存储,可以用来长期保存登录信息 localStorage.getItem('TOKEN')

                sessionStorage的存储时间是当前会话,关闭页面或浏览器就会被清除,可以用来一次性保存登录信息,而且不同浏览器不共享;

4、强缓存和协商缓存

        浏览器缓存主要分为强缓存和协商缓存

Etag:客户端会通过If-None-Match将先前服务器端返回的Etag发送给服务器,服务器会对比这个客户端发送过来的Etag是否与服务器的相同,若相同,就将If-None-Match的值设为false,返回状态304,客户端继续使用本地缓存,不解析服务器端发过来的数据;若不相同就将If-None-Match的值设为true,返回状态为200,客户端重新解析服务器端返回来的数据;

If-Modified-Since:客户端还会通过If-Modified-Since头将先前服务器端发过来的最后修改时间戳发送给服务器,服务器通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回最新内容,如果是最新的,则返回304,客户端继续使用本地缓存;

强缓存:利用http头中的Expires和Cache-Control两个字段来控制,用来表示资源的缓存时间;

        Expires:http1.0的规范,值为绝对时间的GMT格式的时间字符串

        Expires:Mar, 06 Apr 2020 10:47:02 GMT

这个时间代表这个资源的失效时间,只要发送请求是在Expires之前,那么本地缓存始终有效,在缓存中读取数据;

缺点:由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱;

        Cache-Control:http1.1中出现,一般利用该字段的max-age来判断,是一个相对时间

        Cache-Control:max-age=3600 //代表资源有效期为3600秒 

  该字段的其他常用值:

  •         no-cache:不使用本地缓存;需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在Etag,那么请求时就会与服务器端验证,如果验证通过且资源未被修改,则可以避免重新下载;
  •         no-store:直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源;
  •          public:可以被所用的用户缓存,包括中间用户和CDN等中间代理服务器;
  •          private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存;

Cache-Control和Expires同时配置时,Cache-Control的优先级更高;

强缓存的特点:请求时无需访问服务器,加载速度快,性能好,命中时直接返回成功200

未命中强缓存的情况:

  •         响应头中没有Cache-Control和Expires
  •         Cache-Control和Expires过期
  •         Cache-Control属性设置为no-cache

协商缓存:未命中强缓存时,需访问服务器确认当前浏览器的缓存是否过期,若未过期则直接读取,返回304

主要涉及到两组header字段:Etag和If-None-Match;Last-Modify和If-Modified-Since

Last-Mody/If-Modified-Since

        浏览器第一次请求一个资源时,服务器返回的header中会加上Last-Modify,Last-Modify是一个事件表示该资源的最后修改时间;当浏览器再次请求资源时,request的请求头中会包含If-Modified-Since,该值为缓存之前返回的Last-Modify;服务器收到If-Modified-Since后,根据资源的最后修改时间判断是否命中缓存,如果命中则返回304,并且不会返回资源内容和Last-Modify;

Etag和If-None-Match

        Etag(Entity Tag)实体标签,是资源的一个唯一标识,资源变化都会导致Etag变化;服务器根据浏览器上送的If-None-Match值来判断是否命中缓存;

        Etag的出现主要是为了解决:

  •                 一些文件也许会有周期性的更改,但内容不发生改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  •                某些文件修改非常频繁,比如在秒以下的时间内进行修改,If-Modified-Since能检查到的粒度是s级的,这种修改无法判断;
  •                某些服务器不能精确的得到文件的最后修改时间

Last-Modify和Etag可以同时使用,服务器会优先验证Etag,一致情况下才会继续比较Last-Modify,最后才决定是否返回304;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值