前端面试(自给自足版)

内心os:

1.准备充分
2.知识系统
3.沟通简洁
4.内心诚实
5.态度谦虚
6.回答灵活

一面:

1.页面布局

H5最大的特点就是标签语义化,可以使我们和浏览器更好的理解结构与阅读


前端面试(自给自足版)_第1张图片
%`FOJEK0)}L)$5{BP(XDW4C.png

解决方式:5种
1.float
2.position
3.flexbox
4.table
5.网格布局

1.float详解



    
        
        Layout
        
    
    
        

浮动解决方案

1.这是三栏布局中间部分 1.这是三栏布局中间部分

优点:兼容性很好
缺点:浮动是脱离文档流,如果处理不好,会产生很多的局限。

文档流详解:本来这个标签是属于文档流管理的,那么它应该按照文档流的正常布局方式从左至右从上之下,并且符合标签本身的含义。
脱离文档流是指,这个标签脱离了文档流的管理。不受文档流的布局约束了,并且更重要的一点是,这个标签在原文档流中所占的空间也被清楚掉了。

2.position

        

绝对定位解决方案

1.这是三栏布局中间部分 1.这是三栏布局中间部分

好处:快捷,不容易出问题
缺点:因为绝对定位本身脱离了文档流,这就要求下面的子元素也要脱离文档流,它的有效性不是很好

3.flexbox

        

flexbox解决方案

1.这是三栏布局中间部分 1.这是三栏布局中间部分

移动端很多都使用,基本比较完美
flex https://www.jianshu.com/p/37f950238261
这里flex:1 和 flex:2 甚至 flex:10 都是一样的

4.table

        

表格解决方案

1.这是三栏布局中间部分 1.这是三栏布局中间部分

优点:兼容性很好
缺点:当3栏布局中,有一栏的布局,高度增加的时候,其他2个也会同步增加。这个也不算缺点,只是有点局限,根据情况自行使用。

5.grid(网格)

        

网格解决方案

1.这是三栏布局中间部分 1.这是三栏布局中间部分

相当于栅格布局,还是比较完美,

question2:

如果去掉高度已知,哪个布局不再适用:
float position 网格

页面布局小结:

1.语义化掌握到位
2.页面布局理解深刻
3.css基础知识扎实
4.第思维灵活 积极上进
5.代码书写规范

2.CSS盒模型

2.1基本概念:标准模型+IE模型
2.2标准模型和IE模型的区别


前端面试(自给自足版)_第2张图片
image.png

标准模型是content的width height
IE模型是 border+padding+content

2.3CSS如何设置这两种模型
通过设置box-sizing:content-box;(标准,浏览器默认)
box-sizing:border-box; (IE)
来区分两种模型

2.4JS如何获取盒模型对应的宽和高

  1. dom.style.width/height (只能取到内联样式)
  2. dom.currentSytle.width/height
    这个是等到浏览器渲染后,再去取当前dom节点的宽和高,这个是比较准确的,但是有一个缺点,现在只有IE支持。
    3.window.getComputedStyle(dom).width/height
    原理相似,只是这个兼容性更好
    4.dom.getBoundingClientRect().width/height
    同2,3 计算一个元素的绝对位置 能拿到4个 left top width height

2.5实例题 根据盒模型解释边距重叠

前端面试(自给自足版)_第3张图片
image.png

100px 为子元素的高度
问父模型的高度
父模型的高度是100px 还是110px?
这个还是要看父模型的盒模型



    
        
        
        
    
    
        

这种情况父元素的height为100px;
如果在#sec中加了overflow:hidden;
父元素的height变成了110px;

BFC的概念 块级格式化上下文
IFC 内联元素的格式化上下文(问的比较少)

BFC的原理就是BFC渲染规则:
1.在BFC这个元素的垂直方向的边距会发生重叠
2.BFC的这个区域不会与浮动元素的box重叠 (这个是用来清除浮动 和布局的)
3.BFC在页面上是个独立的容器,里面的不会影响外面,外面的不会影响里面。
4.计算BFC元素高度时,浮动元素也会参与计算

如何创建BFC:
overflow:hidden
1.float值不为none 设置浮动-->创建BFC
2.position值不为position: relative或者position: static; -->就为创建了BFC
3.display为

display: table;
display: table-caption;
display: inline-table;

或者table-其他的 都为创建了BFC
4.只要不是overflow:visible;其他的都视为创建了BFC

2.6BFC(边距重叠解决方案)
BFC使用场景:
在这里,因为父元素是BFC:overflow:hidden,所以在BFC这个元素的垂直方向的边距会发生重叠。如何解决?


        

1

2

3

这里给p元素加一个父盒子,然后在父盒子中加了overflow:hidden 让父元素成为了BFC 可以解决p标签垂直方向边距重叠问题


        

这里将right div变为BFC float就不会重叠 跑过去 填左边那缺少的10px


        
我是浮动元素

让子元素为BFC的时候,父元素的高度不再为0px,会加上子元素的高度。

3.DOM事件

前端面试(自给自足版)_第4张图片
image.png
基本概念:DOM事件的级别
前端面试(自给自足版)_第5张图片
image.png

false用于判断捕获还是冒泡

dom1 没有跟事件相关的 所以这里跳过dom1

dom3增加了很多事件,比如:鼠标事件 键盘事件

DOM事件模型 (捕获+冒泡)
DOM事件流
前端面试(自给自足版)_第6张图片
image.png

大白话来解释事件流:浏览器在当前这个页面,也用户做交互的时候,比如说,我点击了鼠标左键,这个左键传递到你的页面上。这就是个事件流。
一个完整的事件流分3个阶段:
1.捕获
2.目标阶段 比如我点了个按钮,这个按钮就是目标阶段
事件通过捕获,到达目标元素,这个就是目标阶段。
3.从目标元素上传到window对象,这就是冒泡

捕获---->目标元素---(上传到window 事件)--->冒泡

描述DMO事件捕获的具体流程

捕获 就是从上-->下


前端面试(自给自足版)_第7张图片
image.png

冒泡的流程 刚好完全相反

如何获取html? 很简单 document.documentelement

Event对象的常见应用

1.捕获跟冒泡的事件流程
2.怎么去注册事件 监听用户的交互行为
3.响应的时候


前端面试(自给自足版)_第8张图片
image.png

event.preventDefault()
作用:阻止默认事件

event.stopPropagation()
作用:阻止冒泡

event.stopImmediatePropagation()
作用:事件响应优先级 比如有2个事件,a和b,如果在a里面添加了这个,那么响应的时候,就会执行a不执行b;



    
        
        
    
    
        

paragraph

很多时候面试的时候会问一个问题:
用for循环给很多li加上点击事件,如何优化这种情况?
这个时候,可以回答使用事件代理,给li的父元素加上一个点击事件,然后当它的子元素得到点击的时候,再去寻找相应的子元素。
如何找到相应的子元素?event.target
事件代理 ---> targe 当前被点击
currentTarget当前被绑定的事件 也就是那个父元素

这篇文章写的比较详细:
https://www.cnblogs.com/liugang-vip/p/5616484.html

自定义事件
前端面试(自给自足版)_第9张图片
image.png

customEvent和event都是自定义事件,区别在于:customEvent可以加参数




    
        
        
    

    
        

模拟捕获过程:




    
        
        
    

    
        
鼠标元素
前端面试(自给自足版)_第10张图片
image.png

冒泡 反之

模拟自定义事件:
在这里模拟customEvent:

//customEvent
            var myEvent=new CustomEvent("userLogin",{
                detail:{
                    username:"zhangjing"
                }
            });
            
            ev.addEventListener('userLogin',function(e){
                console.log(e.detail.username)
            })
            
            ev.dispatchEvent(myEvent);

输出结果:

zhangjing

4.HTTP协议

HTTP协议的主要特点

前端面试(自给自足版)_第11张图片
image.png

简单快速:因为为http中每一个资源 也就是uri的是固定的,比如一个页面一张图片都是固定的,叫做统一资源符(uri),所以要访问就很轻松快速。

灵活:它在头部有一个数据类型,通过一个http协议可以完成不同的数据类型的传输。

无连接:连接一次就会断掉 不会保存连接

无状态:不能区分2次连接者的身份

HTTP报文的组成部分

前端面试(自给自足版)_第12张图片
image.png

请求行包含什么?HTTP方法、页面地址、HTTP协议、版本


image.png

请求头包含什么?key value值 告诉服务端 我要的内容需要注意什么格式,协助客户端对服务器的请求


前端面试(自给自足版)_第13张图片
image.png

空行:区分请求头跟请求体
请求体:请求的东西

响应实例:
响应行:


image.png

响应头:


前端面试(自给自足版)_第14张图片
image.png

HTTP方法


前端面试(自给自足版)_第15张图片
image.png

POST和GET的区别


前端面试(自给自足版)_第16张图片
image.png

get请求在url中传送的参数 一般<2kb 不要拼接太长,太长了服务器会截断,然后http就没法发出去,导致错误。

HTTP状态码


前端面试(自给自足版)_第17张图片
image.png
前端面试(自给自足版)_第18张图片
image.png
前端面试(自给自足版)_第19张图片
image.png

401 一般来说该错误消息表明您首先需要登录(输入有效的用户名和密码)。 如果你刚刚输入这些信息,立刻就看到一个 401 错误,就意味着,无论出于何种原因您的用户名和密码其中之一或两者都无效(输入有误,用户名暂时停用等) 。

403被禁止 也可表示资源不可用

什么是持久连接


前端面试(自给自足版)_第20张图片
image.png

http1.1版本才支持

什么是管线化


前端面试(自给自足版)_第21张图片
image.png

->表示没有断开


前端面试(自给自足版)_第22张图片
image.png

重点:1.2.3

5.原型链


前端面试(自给自足版)_第23张图片
image.png
前端面试(自给自足版)_第24张图片
image.png


    
        
        原型链
    
    
        
    

输出结果:


前端面试(自给自足版)_第25张图片
image.png
前端面试(自给自足版)_第26张图片
image.png

注意:
任何一个函数 只要被new了 就可以被称为构造函数
for example:var o2=new M(); -》M是一个构造函数

强调:
函数才有prototype 对象是没有prototype的
只有对象才有proto 函数既是函数 也是对象 js万物皆对象

前端面试(自给自足版)_第27张图片
image.png
前端面试(自给自足版)_第28张图片
image.png

用constructor去判断o3是谁的实例 比 用instanceof判断更加准确。instanceof会将一整条原型链上的 都判断为true。

前端面试(自给自足版)_第29张图片
image.png
//          第三种方式:object.create
            var p={name:'p'};
            //Object.create 创造的o4是通过原型链 来连接的
            var o4=Object.create(p);
            
            m.prototype.say=function(){
                console.log('say hi');
            }
            
            var o5=new m();
            
            //new 背后的工作原理
            var new2=function(func){
                var o=Object.create(func.prototype);
                var k=func.call(o);
                if(typeof k ==='object'){
                    return k
                }else{
                    return o
                }
            }

6.面向对象

前端面试(自给自足版)_第30张图片
image


    
        
        面向对象
    
    
        
    

输出结果


image.png

继承的本质就是原型链

js的继承有几种方式,优缺点?

//借助构造函数实现继承(部分继承)
            function parent1(){
                this.name='parent1';
            }
            parent1.prototype.say=function(){
                this.say='123';
            }
            function child1(){
                //实现继承  将父级元素的this指向子构造函数上去
                parent1.call(this);//apply 皆可  
                this.type='child1';
            }
            console.log(new child1())

它的本质是将父元素的this指向子元素的构造函数上,并没有通过原型链,所以他只能部分继承,child1没有继承say方法。

//借助原型链实现继承
            function parent2(){
                this.name='parent2';
            }
            function child2(){
                this.type='child2';
            }
            child2.prototype=new parent2();
            
            console.log(new child2());
            console.log(new child2().__proto__);

输出


前端面试(自给自足版)_第31张图片
image.png
image.png

缺点:
先用代码演示一遍:
首先 我们在父级构造函数中加一个play属性

            function parent2() {
                this.name = 'parent2';
                this.play = [1, 2, 3]
            }

然后new 2个实例对象出来

            var s1 = new child2();
            var s2 = new child2();
            console.log(s1.play, s2.play);
            s1.play.push(4);

这时候我们在console去看一下

前端面试(自给自足版)_第32张图片

改变s1的同时 s2也得到了改变 为什么呢?
因为他们俩的 “proto”都是new出来的parent2对象,根据原型链,找到play,并且push一个4 ,所以所有都会变

前端面试(自给自足版)_第33张图片

但是不会改变父构造函数。
如果再加上这句:

s2.play.push(5);
前端面试(自给自足版)_第34张图片
image.png
//组合方式
            function parent3(){
                this.name='parent3';
                this.play=[1,2,3];
            }
            function child3(){
                parent3.call(this);
                this.type='child3';
            }
            child3.prototype=new parent3();
            var s3=new child3();
            var s4=new child3();
            s3.play.push(4);console.log(s3.play,s4.play);

优点:结合了构造函数继承和原型链继承的优缺点,比较完美
缺点:new了2次parent3 将parent3实例化了2次 2次的意义不大,浪费资源

//组合继承的优化
            function parent4(){
                this.name='parent4';
                this.play=[1,2,3];
            }
            function child4(){
                parent4.call(this);
                this.type='child4';
            }
            child4.prototype=parent4.prototype;
            var s5=new child4();
            var s6=new child4();
            console.log(s5,s6);
            
            console.log(s5 instanceof child4,s5 instanceof parent4);
            console.log(s5.constructor,child4.constructor); 

优点:解决了上一个问题 不再new2次
缺点:他们的constructor指向的同一个构造函数,无法区分是又子类创建的还是由父类创建的

//组合继承优化2
            function parent5(){
                this.name='parent5';
                this.play=[1,2,3];
            }
            function child5(){
                parent5.call(this);
                this.type='child5';
            }
            child5.prototype=Object.create(parent5.prototype);
            //观察__.proto__,以下为优化步骤
            child5.prototype.constructor=child5;
            var s7=new child5();
            console.log(s7 instanceof child5,s7 instanceof parent5);
            console.log(s7.constructor);

输出:
在执行优化步骤之前:


前端面试(自给自足版)_第35张图片
image.png

执行之后:


前端面试(自给自足版)_第36张图片
image.png

完美解决。

Q4:typeof 和 instanceof 区别。
A:
typeof 的返回值为‘number’,‘string’,’boolean’,’function’,’undefined’,’object’。所以在判断数组时,返回值为 ‘object’;
instanceof 是判断变量是否为某个对象的实例,返回值布尔值。

7.通信 跨域+普通前后端

前端面试(自给自足版)_第37张图片
image.png
前端面试(自给自足版)_第38张图片
image.png

IndexDB利用数据键(key)访问,通过索引功能搜索数据,适用于大量的结构化数据,如日历,通讯簿或者记事本。

一个源包含什么?协议+域名+端口(默认端口:80)
这3个当中 如果有一个不一样,那就是跨域通信

不是同一个源的文档 无法去操作另一个源的文档或者资源

这里的限制有这么几个:


前端面试(自给自足版)_第39张图片
image.png
前端面试(自给自足版)_第40张图片
image.png
前端面试(自给自足版)_第41张图片
image.png

1.ajax是同源下面的通信
2.websocket 是没有限制的 就是不受同源限制
3.cors 支持跨域,支持同源

前端面试(自给自足版)_第42张图片
image.png

XMLHttpRequest只有高级浏览器才支持 IE是不支持的 所以要考虑兼容性的处理

手写ajax,第一版本:

function ajax(url, fnSucc, fnFaild) {
                //1.创建Ajax对象
                if(window.XMLHttpRequest) { //该判断是为了兼容ie6
                    var oAjax = new XMLHttpRequest();
                } else {

                    var oAjax = new ActiveXObject("Microsoft.XMLHTTP");
                };

                //2.连接服务器
                //open(方法,文件名,异步传输)
                //'a.txt?t='+new Date().getTime()可以组织缓存
                oAjax.open('GET', url, true);

                //3.发送请求
                oAjax.send();

                //4.接收返回
                oAjax.onreadystatechange = function() {
                    //                          oAjax.readyState  //服务器和浏览器,进去到哪一步了
                    if(oAjax.readyState == 4) {
                        if(oAjax.status == 200) {
                            fnSucc(oAjax.responseText);
                        } else {
                            if(fnFaild) {
                                fnFaild(oAjax.status);
                            }
                        }

                    }
                }
            }

readyState的5个状态码:
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
版本二,详细版本:

if(opt.url){
                var xhr=XMLHttpRequest?new XMLHttpRequest():new window.ActiveXObject('Microsoft.XMLHTTP');
                var data=opt.data,
                      url=opt.url;
                      type=opt.type.toUpperCase(),
                      dataArr=[];
                for(var k in data){
                    dataArr.push(k+'='+data[k]);
                }
                if(type==='GET'){
                    url=url+'?'+dataArr.join('&');
                    xhr.open(type,url.replace(/\?$/g,''),true);
                    xhr.send();
                }
                if(type==='POST'){
                    xhr.open(type,url,true);
                    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
                    xhr.send(dataArr.join('&'));
                }
                xhr.onload=function(){
                    //206  适用于媒体资源  可以再加一个xhr.status===206
                    if(xhr.status===200||xhr.status===304){
                        var res;
                        if(opt.success&&opt.success instanceof Function){
                            res=xhr.responseText;
                            if(typeof res==='string'){
                                res=JSON.parse(res);
                                opt.success.call(xhr,res);
                            }
                        }
                    }else{
                        if(opt.error && opt.error instanceof Function){
                            opt.error.call(xhr,res);
                        }
                    }
                }   
            }

框架下 如何使用ajax
1.jquery

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

2.mui下的

mui.ajax('http://server-name/login.php',{
    data:{
        username:'username',
        password:'password'
    },
    dataType:'json',//服务器返回json格式数据
    type:'post',//HTTP请求类型
    timeout:10000,//超时时间设置为10秒;
    headers:{'Content-Type':'application/json'},                  
    success:function(data){
        //服务器返回响应,根据响应结果,分析是否登录成功;
        ...
    },
    error:function(xhr,type,errorThrown){
        //异常处理;
        console.log(type);
    }
});
前端面试(自给自足版)_第43张图片
image.png

jsonp应该接触的都比较多了

很简单,就是利用 并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。 第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),形如: callback({"name":"hax","gender":"Male"}) 这样浏览器会调用callback函数,并传递解析后json对象作为参数。本站脚本可在callback函数里处理所传入的数据。 补充:“历史遗迹”的意思就是,如果在今天重新设计的话,也许就不会允许这样简单的跨域了嘿,比如可能像XHR一样按照CORS规范要求服务器发送特定的http头。

hash是什么?就是你url地址中#后面的东西 hash的变动页面不会刷新 这就是用hash做页面快通讯的一个原理 hash改变 页面不刷新

search是url中?后面的东西,search改变,页面是会刷新的 search不能做快通讯

postMessage H5中新增的处理快通讯

websocket 不收同源限制

CORS支持跨域通讯的ajax 大白话来理解就是:浏览器在识别你发送了一个ajax的跨域请求的时候,它会在你的http头中加一个origin来允许跨域通信。这就是cors,如果是普通的ajax的话,如果要跨域请求的时候,浏览器就会把你拦截了。

jsonp的原理是什么?


        
        
        

这里data=name 这一块可要可不要 主要是要把callback=jsonp 然后jsonp是个本地的全局函数 执行了script的时候就会去找jsonp这一块。

var util = {};

            //在页面中注入js脚本
            util.createScript = function(url, charset) {
                var script = document.createElement('script');
                script.setAttribute('type', 'text/javascript');
                charset && script.setAttribute('charset', charset);
                script.setAttribute('src', url);
                //script标签异步执行
                script.async = true;
                return script;
            }

            util.jsonp = function(url, onsuccess, onerror, charset) {
                //告诉它回调名称
                var callbackName = util.getName('tt_player');
                //在全局注册这么个回调函数
                window[callbackName] = function() {
                    if(onsuccess && util.isFunction(onsuccess)) {
                        onsuccess(arguments);
                    }
                }
                //动态创建script标签
                var script = util.createScript(url + '&callback=' + callbackName, charset);
                //script加载
                script.onload = script.onreadystatechange = function() {
                    if(!script.readyState || /loaded|complete/.test(script.readyState)) {
                        script.onload = script.onreadystatechange = null;
                        // 移除该script的 DOM 对象
                        if(script.parentNode) {
                            script.parentNode.removeChild(script);
                        }
                        // 删除函数或变量
                        window[callbackName] = null;
                    }
                };
                script.onerror = function() {
                    if(onerror && util.isFunction(onerror)) {
                        onerror();
                    }
                };
                //向html中增加这个标签
                document.getElementsByTagName('head')[0].appendChild(script);
            }

使用jsonp的例子:

$.ajax({
            type: "get",
            async: false,
            url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
            dataType: "jsonp",
            jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
            jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
            success: function(json){
                alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
            },
            error: function(){
                alert('fail');
            }
        });

这里针对ajax与jsonp的异同再做一些补充说明:

1、ajax和jsonp这两种技术在调用方式上”看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装。

2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加
Hash:

 // 利用hash,场景是当前页面 A 通过iframe或frame嵌入了跨域的页面 B
      // 在A中伪代码如下:
      var B = document.getElementsByTagName('iframe');
      B.src = B.src + '#' + 'data';
      // 在B中的伪代码如下
   //当hash变化的时候
      window.onhashchange = function () {
          var data = window.location.hash;
      };

postMessage:

// postMessage
      // 窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
      Bwindow.postMessage('data', 'http://B.com');
// 这里的data一般是string字符串, 'http://B.com'是源,也可以用*,*代表任意的都可以,但是不安全,不建议使用
      // 在窗口B中监听
      Awindow.addEventListener('message', function (event) {
          console.log(event.origin);
          console.log(event.source);
          console.log(event.data);
      }, false);

websocket:

 // Websocket【参考资料】http://www.ruanyifeng.com/blog/2017/05/websocket.html

      var ws = new WebSocket('wss://echo.websocket.org');
      //wss 用于加密
      ws.onopen = function (evt) {
          console.log('Connection open ...');
          ws.send('Hello WebSockets!');
      };

      ws.onmessage = function (evt) {
          console.log('Received Message: ', evt.data);
          ws.close();
      };

      ws.onclose = function (evt) {
          console.log('Connection closed.');
      };

CORS:

// CORS【参考资料】http://www.ruanyifeng.com/blog/2016/04/cors.html
      // url(必选),options(可选)
      fetch('/some/url/', {
          method: 'get',
      }).then(function (response) {

      }).catch(function (err) {
        // 出错了,等价于 then 的第二个参数,但这样更好用更直观
      });

8.安全 xss


前端面试(自给自足版)_第44张图片
image.png
前端面试(自给自足版)_第45张图片
image.png
前端面试(自给自足版)_第46张图片
image.png
前端面试(自给自足版)_第47张图片
image.png

用户--登录--->网站A 然后 网站A---下发cookie--->用户
这个过程就是一个网站登录验证的过程

这个用户必须要登录过
会产生csrf:
1.网站中某个接口有问题
2.用户在该网站登录过

前端面试(自给自足版)_第48张图片
image.png

token验证:
比如:用户要去访问一个网站,然后服务器那边会自动给出一个token,这时候就不止是cookie还有token,如果想上一个环节那样,引诱用户去点一个链接,这个链接只会自动携带cookie而不会携带token,就避免了那个攻击。

referer验证:referer指的就是页面来源,服务器可以判断来的这个页面是不是我的站点下的页面,如果是,我就执行你的这个动作,如果不是,一律拦截,这样也可以避免攻击。

隐藏令牌:类似token,只是它放的比较隐蔽,比如说我隐藏在http head头中,而不会放在链接上,这样比较隐蔽。

前端面试(自给自足版)_第49张图片
image.png
前端面试(自给自足版)_第50张图片
image.png

攻击原理:就是注入js脚本,找各种合法路径,然后给你注入js脚本。
防御措施:就是让xss不执行。

xss跟crfs的区别:
xss是向你的页面注入js脚本运行,在js函数体里面去做它想做的事情。
crfs是利用你本身漏洞,帮你去执行那些接口,且依赖于用户必须要登录注册该网站。

9.算法

前端面试(自给自足版)_第51张图片
image.png

堆栈 先进后出 队列 先进先出

前端面试(自给自足版)_第52张图片
image.png
前端面试(自给自足版)_第53张图片
image.png
前端面试(自给自足版)_第54张图片
image.png
前端面试(自给自足版)_第55张图片
image.png
前端面试(自给自足版)_第56张图片
image.png

你可能感兴趣的:(前端面试(自给自足版))