新年伊始,万象更新。过去的一年,在掘金的点点滴滴,记录了我的学习过程,在这新的一年里,我也将持续创作。
前些天投了几份简历,约了场面试,基于对以往学长学姐笑谈被面试官虐的心理,我当时的内心忐忑不安,紧张万分。说实话,听别人说好像就是很遥远的事情,一旦你走到这一步,感觉一切都始料不及,很栓Q~。不过还好,这场面试跟我想象的不太一样,面试官们没有在我结结巴巴地介绍完自己后,抓八股文,抓HTTP等等,而是从简历入手,着手项目所写的,根据你的项目来进行提问,以及一些遇到实际问题,以你现在的技能,你该如何处理。
看到这个,你也许会松一口气,心里想:“这不是很人性嘛?自己写的当然都烂熟于心了。”实话实话,会用还不是高,我们进入正题吧,以下问题是基于项目的问题,也是基于必备的知识储备。
一、在跨域这方面,你遇到了什么问题?具体如何解决的?
这里首先就是要明白什么是跨域,为什么要跨域,不跨域是怎么样的。我们要知道只有浏览器会发生跨域问题,这是源于浏览器的同源策略,并且浏览器跨域 Access-Control-Allow-Headers 问题。而关于什么是跨域?跨域出现的问题是什么?如何解决跨域?这些问题,这里就不再长篇大论了,有需要巩固可查看文章跨域小知识
因为我是使用cors(Cross-origin resource sharing)解决跨域的,而cors解决跨域的原理是:服务器设置Access-Control-Allow-Origin:*; ,即所有的源都允许,开启cors。然而,设置所有的源都允许的话,有什么潜在的风险呢?这也正是面试官所问到的,说实话我当时真没有这么了解,印象不深了,只是笼统的说了,更容易遭受不良网站的攻击,这么说,面试官肯定认为我是在耍流氓了,栓Q~~。
所以我了解到:
(1)使用cors解决跨域,cors中文名叫跨站资源共享。顾名思义,cors就是一个盲目的协议,只是通过HTTP头来控制,从而存在很多风险:第一,HTTP头只能说明请求来自一个特定的域,但是不能保证这个事实,因为HTTP头可以被伪造,换句话说,未经身份验证的跨域请求是永远不会被信任的;第二,既然所有的源都允许的话,那么第三方就更加肆无忌惮地入侵了,打个比方说,A为使用cors配置不当的网站,B为攻击者伪造的任意恶意网站,这个恶意网站含有恶意脚本,向网站A请求用户个人数据,而当用户访问网站A的时候,并且被攻击者诱骗点开了恶意网站B,此时恶意脚本会绕过网站A的服务端配置的cors校验规则,拿到受害人的私密数据,从而达到窃取用户个人信息的目的。总而言之,就是第三方有可能被入侵,恶意跨域请求,内部信息泄漏等等,那么这个又该如何解决呢?对于cors的漏洞,还需要严格控制信任域,最好的方式就是通过白名单配置cors策略。
另外,使用jsonp跨域,proxy跨域有什么风险嘛?这些问题自己去寻找答案会更加的印象深刻,这里就不多说了。
二、使用jwt生成Token,Token是如何传给前端的,前端又是如何处理的?
项目里的流程大致是这样的:用户在登录或注册的时候,随着用户信息传递给后端,后端将根据用户信息判断在数据库存在与否,如果存在,后端通过jwt.sign()
方法根据用户的信息生成Token,从而向前端返回一些数据的时候,将Token也一并返回,前端拿到Token后,使用pinia状态管理器进行存储,而后在封装axios时,拿到存储的Token,将Token设置在config.headers.authorization
字段,从而每次向后端发请求,请求都会携带上Token字段,后端拿到前端请求携带的Token,通过jwt.verify()
校验Token的合法性,拒绝伪造的Token。
三、存储在cookie和存储在localStorage里有什么不同?
(1)cookie
只能保存4kb左右的信息,本身是用于浏览器和server的通讯,是借用于本地存储,修改方式单一,只能通过document.cookie
进行修改;cookie也可以设置失效时间,没有设置的话,默认是关闭浏览器后失效;另外的话,实际上原生的cookie接口并不友好,需要程序员自己手动封装。
另外,每次发HTTP请求都会携带cookie信息,多多少少有些浪费宽带;cookie不支持跨域调用,需要指定作用域,限制比较多。
(2)localStorage
可以保存5MB的信息,仅在客户端(即浏览器)中保存,不参与和服务器的通信,是永久缓存,之后不是代码删除或者手动、强制刷新删除,会一直保留在浏览器的缓存里,也可以跨页面传递参数;
(3)sessionStorage
可以保存5MB的信息,仅在客户端(即浏览器)中保存,不参与和服务器的通信,是临时缓存,会话结束(网页关闭),缓存就不存在了,只是保存一些临时数据,防止用户刷新页面之后丢失参数;
localStorage和sessionStorage的原生接口可以接受,也可以再次封装,使用方便,都有两个方法,setItem()和getItem,分别是设置缓存和获取缓存。
四、关于浏览器的缓存策略,你了解哪些?
强缓存和协商缓存。具体可参考其他文章。
五、打包文件都有固定的地址,那为什么文件名字每次打包都不一样?
首先,应用打包部署后,为防止客户端反复请求支援,服务器一般都会设置缓存,从而减少带宽流量压力,这就会出现,打包后应用没有及时更新的缓存问题,我们知道每次打包如果代码没有发生修改,就是用缓存,若发生了变更,就不使用缓存,这个时候就可以在打包后的文件名做手脚,保证每次打包生成的和上一次打包生成的文件名字不同,全新的文件名就代表全新的请求,每次保持唯一性的文件名,保证不与历史文件名重名,也是文件的版本号。就像webpack,webpack为了解决这样的缓存问题,在生产环境下,webpack每次打包都会使用内容的hash值作为文件的版本号生成文件名中。
以上面试问题实际上只是涉及到的一部分,还有一些偏向于具体问题具体分析,很多知识也许是经常接触的,但是就是会有知识的关键点会忽略,细节就在这里显得颇为重要了~。