1.浏览器本地存储
(1)Localstorage和SessionStorage
- 生命周期:前者永久(不清除的话),后者结束会话清除。
- 使用:同一浏览器不同页面可以共用前者,后者不可以
- 大小:均为5mb。
- api:均有丰富api如下。
- 通信:均不参与通信。
Localstorage.setItem(“key”,”value”)
Localstorage.getItem(“key”)
Localstorage.removeItem(“key”)
Localstorage.clear()
(2)Cookie与Session
- cookie和session都是用来跟踪浏览器用户身份的会话方式。
- 大小:cookie大概4k,session不受限
- 生命周期:
cookie不设过期事件就成活cookie,会话结束清除。反之定期清除。
session在一段时间后会在服务端自动清除。 - 类型:cookie只能保存字符串,session支持任何类型对象。
- 保存位置:cookie在客户端,session在服务端。
- 安全性:session比cookie安全:
① sessionid存储在cookie中,若要攻破session首先要攻破cookie;
② sessionid是加密的。
③session本题设置再服务端
域名方面cookie的作用域是当前domain以及domain的子域名,domain可以设置为当前域名或者父域名
路径方面根据path,设置为根路径则该应用所有目录都能拿到
解析cookie方法(基于cookie是键值对形式):
var parseCookie = function(cookie){
var cookies = [];
if(!cookie) return cookies;
var arr = cookie.split(';');
for(let i = 0;i < arr.length;i ++){
var pair = list[i].split('=');
cookies[pair[0].trim()] = pair[1];
}
return cookies;
}
cookie的性能影响:
原因:所有对应域下的请求都会带上cookie,而对于有些请求(比如说静态文件请求)是没用的。
解决对策:设置不同的域名。
path:设定的值为服务端能拿到该cookie的路径(包括path的子路径)
domain:指使用这个cookie的域名范围,比如t2.test.com就只有这个域名能使用,.com表示所有域名包括.com的都能用
总而言之,domain和path都是设置cookie的是否携带,只不过domain是域名层面的,path是路径层面的
(3)Session与token
token会用请求加token加时间戳三者进行加密
session的流程:
- 发送http请求请求登录。
- 用户登录成功后服务器建立一个session,将Set-Cookie头部发送给客户端。该头部包含了sessionId。
- 客户端再次访问服务器,自动在请求头中添加cookie
- 服务器接收请求,分解cookie,验证信息,核对成功后返回response给客户端
token流程与session类似:
- 发送http请求请求登录。
- 用户登录成功后服务器返回Token给客户端。
- 客户端收到数据后保存在客户端
- 客户端再次访问服务器,将token放入headers中
- 服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码
(4)token可以抵抗csrf,cookie+session不行
因为token不会自动地放在headers中,所以攻击者无法偷取token。
第二点是因为token可以使用请求拦截进行查看和验证来确定对方是否为csrf。
(5)前端权限控制不能用session,但是用cookie又不安全,只能用token
2.常见HTTP状态码
(1)200,ok。201,服务器创建了新资源。204,没有资源可以返回。206表示客户端进行了范围请求。
(2)301,重定向,包含一个新的url,防止url变更导致老url失效。302,暂时性重定向。303,表示所请求资源指向另一个资源,要用get访问。304所请求的资源未修改,服务器不会返回任何资源。客户端通常会缓存访问过的资源。307也是重定向,但是不会自动将post自动转为get再次发送请求。
(3)400报文存在语法错误,401,需要进行http验证。404,无法将url转为资源。410的话请求的资源曾经存在,但现在不存在。
403服务器理解请求客户端的请求,但是拒绝执行此请求。405,客户端请求中的方法被禁止。407客户端必须在代理服务器上进行身份验证
(4)500,服务端出现错误。
永久重定向浏览会进行缓存,直接用新地址替换旧地址,而暂时重定向下次访问依然会重新请求。
302与301详解,
302暂时重定向,每次访问都会对目标地址请求,通过返回的302报文中的location进行再次访问
而301访问后浏览器会记住重定向location,以后直接访问重定向后的地址
3.如何优化页面加载速度(前端优化有哪些)
(1)优化网络
三合四使
- 合理的设置http缓存(强缓存和协商缓存)。
- 合并js、css,进行文件压缩(如果有多路复用了那么合并js文件就意义不大了)
- 合并http请求(减少dns解析的时间和tcp握手时间)
- 使用cdn
- 使用懒加载
- 使用图片优化(雪碧图,压缩图,剪裁图)
- 使用SSR(服务端渲染)
应为服务端渲染只需要请求一次,并且在服务端完成模板解析,而客户端渲染需要在客户端完成模板解析,并且脚本中如果有请求需要再到服务端进行请求
如何查看是否为服务端渲染?如果右键查看源代码是页面完整的代码那就是服务端渲染。
服务端渲染有利于爬虫,效率高。客户端渲染更灵活,且不需要刷新页面。
(2)事件委托
(3)动画加速
- transform
- opacity
- filter
(3)优化浏览器渲染
1.减小页面体量(虚拟滚动,监听滚动,复用可视区域的dom)
2.合并重排操作
3.对重排对象脱离文档
- 减少重排,将多次触发重排的dom合并或分批操作(用requestAnimationFrame)或者使用虚拟滚动(就是懒加载)或者脱离文档
- 怎么合并dom操作:不要频繁修改dom的样式,用修改class或者修改csstext来实现;使用fragment文档片段。
- 虚拟滚动:监听滚动,根据当前scrolltop截取数组,最后将截取的数组和dom进行绑定。
4.为什么使用axios不使用ajax
1.因为axios提供了一些并发请求的接口,
2.可以在node.js中使用,
3.而ajax项目过大引入jquery不合理
5.New操作的过程
1.创建一个空的对象
2.构造函数中的this指向该对象,同时还继承了构造函数的原型,将该对象的__proto__指向构造函数的prototype
3.在构造函数中使用this给他赋予属性
4.返回这个空对象
6.怎么解决跨域问题
1.跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。但是第三方的接口还是可以使用的,只不过不能解析和读取报文内容而已,但是不影响csrf攻击。对于接口来说,一般只要有对应domain的cookie,也就是有登陆态,就可以正常调用。
因为不同源的脚本如果在没有授权的情况下就能读到目标地址的脚本,这样会存在安全问题。
有三种资源可以进行跨域,css、js、img
2.方法一 jsonp
jsonp通过j动态添加script实现,本质都是在请求端设置回调函数,服务端将带着数据的回调函数返回。
只能用get方法,而且将字符串作为脚本容易受xss攻击。
$.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');
}
});
3.方法二 CROS Cross-origin resource sharing预请求setHeader
resp.setHeader("Access-Control-Allow-Origin", "*");
表示表示支持所有网站访问,也可以额外配置相应网站。这个是在服务端配置的。
4.方法三,使用axios,在index.js中配置proxytable,利用代理服务器进行跨域
7.javascript中的this
this的指向是由它所在函数调用的上下文决定的,而不是由它所在函数定义的上下文决定的。
就是说指向function外面一层。
1)、在全局执行环境中使用this,表示Global对象,在浏览器中就是window对象。
2)、如果函数显示地作为一个非window对象的属性,那么函数中的this就代表这个对象。否则为window。
3)、当通过new运算符来调用函数时,函数被当做一个构造函数,this指向构造函数创建出来的对象。
4)、apply和call的this指的都是第一个参数
8.JS哪些操作会造成内存泄露
1.意外的全局变量引起的内存泄露
2.闭包引起的内存泄露(闭包就是函数中的函数)
闭包可以维持函数内局部变量,使其得不到释放。 上例定义事件回调时,由于是函数内定义函数,并且内部函数–事件回调的引用外暴了,形成了闭包。
解决之道,将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用。
3.被遗忘的定时器或者回调
4.没有清理的DOM元素引用
解决方案:
1.给键值对提供最大长度,然后内部进行FIFO、LRU或者LFU算法进行淘汰
2.由于模块都是常驻内存,存活在老生代内存中,因此对于某些模块需要提供清空内存接口
3.关注任务队列状态,监控队列长度,提供拒绝模式,提供超时回调
9.箭头函数和普通函数有什么区别
1、箭头函数没有自己的this,继承外层代码块的this。
2、不能当做构造函数,也就是说不可以使用new命令,否则会报错的。
3、不能使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
4、不能使用yield命令,因此箭头函数不能用作 Generator(生成器) 函数。
5、因为没有this,所以不能使用call、bind、apply来改变this的指向。
6、箭头函数的参数。
10.怎么理解闭包
闭包是指有权访问另外一个函数作用域中的变量的函数,内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
函数套函数,在执行过程完毕后,返回函数,子函数内部状态得到保存,即使外部状态已经销毁。闭包的this是window。
闭包的作用: 正常函数执行完毕后,里面声明的变量被垃圾回收处理掉,但是闭包可以让作用域里的变量,在函数执行完之后依旧保持没有被垃圾回收处理掉,即延长生命周期
缺点:闭包会导致内存占用过高,因为变量都没有释放内存
闭包函数的应用:
1.创建一个闭包,将其赋值给一个变量,那么调用该函数的时候只需要调用这个变量就可以了。
2.
11.讲讲输入完网址按下回车,到看到网页这个过程中发生了什么
1.判断是否有永久重定向。
2.有缓存则获取缓存的header信息,根据其中的expires(存绝对时间)和cache-control(存相对存在时长)判断是否命中强缓存),不命中则到服务器校验协商缓存last-modified、if-modified-since、E-tag、if-none-match。
请求报文携带的是if-modified-since和if-match-none
3.组装http请求
4.dns解析
过程:
(1)客户端从url解析出域名
(2)客户端向DNS服务器发出域名查询请求
这中间会遇到以下的缓存
- 本机缓存(浏览器缓存和hosts文件记录)
- 路由器缓存
- dns查询(迭代查询)
- 首先查本地域名服务器,查不到迭代到根服务器查询,
- dns查询的时候用的udp查询,而dns服务器之间进行区域传送的时候用的是tcp
5.tcp三次握手,如果涉及ssl - syn和ssl相关信息(版本,加密算法,秘钥长度)
- syn,ack附带ssl相关信息、数字证书和公钥
- ack,检验合法性并且发送对称加密钥匙
6.发送http请求
7.服务端返回响应报文,如果缓存新鲜返回304
8.客户端收到报文,如果可缓存就缓存
9.选择保留连接或者四次握手
10.处理资源:解析HTML文档,构件DOM树,构造CSSOM树,执行js脚本
11.根据DOM树和CSSOM树构建渲染树,发布内容和计算样式
12.你常使用的库有哪些?常用的前端开发工具?
jQuery,bootstrap,lodash。hbuilder和hbuilderx和tortoisegit。
lodsh之深拷贝:_.cloneDeep(value)
tortoisegit是一个图像化方便git操作的工具。
13.安全性问题(别的网站使用爬虫技术爬你的网站怎么办?有没有安全措施)
单位时间内请求次数超过某个阈值就让输入验证码,可以极大降低抓取的速度,如果多次超过某个阀值可以加入黑名单。还有就是页面内容使用 json 返回,数据经常变一变格式,或者js动态生成页面内容。
14.请解释一下 JavaScript 的同源策略
同域名,同端口,同协议
15. .ajax的原理和步骤
Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
(2)创建一个新的HTTP请求,并指定该1.HTTP请求的方法、2.URL及3.验证信息.
(3)设置响应HTTP请求状态变化的函数.(前三点是准备)
(4)发送HTTP请求.
(5)获取异步调用返回的数据.
(6)使用JavaScript和DOM实现局部刷新.
具体参考https://www.cnblogs.com/dzj1/p/10767092.html
var xhr=new XMLHttpRequest();
//0 : 未初始化,还未调用open方法
xhr.open("POST",url,true);
xhr.setRequestHeader(header);
xhr.send(data)
//1 :载入中,已调用sned方法发送请求
xhr.onreadystatechange=function(){
if(xhr.status>=200||xhr.status<300||xhr.status==304){
console.log(xhr.responseText);
}
}
2 :载入已完成,send方法执行完成,已收到全部响应信息
3 :交互,正在解析响应内容
4 :完成,响应内容解析完成
16.一次js请求,一般会有哪些缓存处理
DNS缓存:短时间内多次访问某个网站,在限定时间内,不用多次访问DNS服务器。
CDN缓存:内容分发网络(人们可以在就近的代售点取火车票了,不用非得到火车站去排队)
浏览器缓存:浏览器在用户磁盘上,对最新请求过的文档进行了存储。
服务器缓存:将需要频繁访问的Web页面和对象保存在离用户更近的系统中,当再次访问这些对象的时候加快了速度。
17.一个页面上有大量的图片,加载很慢,你有哪些方法优化这些图片的加载?
1.图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
2.如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
3.如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
4.如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致。
18.get、 post的区别
-
get 传参方式是通过地址栏URL传递,能直接看到get传递的参数,在URL后通过?连接,通过&进行参数分割。
post传参方式参数URL不可见,存放在HTTP的包体内。 -
get 对传递的数据长度受URL的限制,URL最大长度是2048个字符。 post 没有长度限制
-
get后退页面不会有影响,post后退会重新进行提交 get请求可以被缓存,post不可以被缓存
-
get请求只URL编码,post支持多种编码方式 get请求的记录会留在历史记录中,post请求不会留在历史记录
get只支持ASCII字符,其他字符通过编码会转换,post没有字符类型限制 -
post的缺点:速度比get传输慢,get的效率更高
post优点:安全性比get传参方式好(并不代表post一定安全,因为在HTTP下都是明文传输,post仍然可以被查找到,增加安全性最好使用https协议)
- 为什么get的效率比post高(扩展)
1.post接收返回的数据:先将请求头发送给服务器确认,然后才真正的发送数据,get则是直接发送数据。 专业的说法是:get产生一个TCP数据包,post产生两个TCP。 总结:请求的过程比get更多
2.get会将数据进行缓存
18.cookie包含哪些信息?
这个取决于网站自身,网站会存储一些重要的用户信息,包括用户名、密码、浏览记录、IP地址什么的都记录到Cookies里。事实上:普通网站都不会存这些重要的信息,它们仅仅存一个你的登陆状态,也就是你拿用户名密码换取的令牌(sessionid token)。
19.懒加载的方法
1.监听滚轮事件,检查目标是否在视窗中,触发替换图片行为。
2.IntersectionObserver,浏览器内置,添加监听,当图片可见性变化时触发回调,替换图片。
3.getBoundingClientRect().top,节流监听滚轮事件当元素距离可视区域的距离小于可视高度时加载