1. Token过期了怎么办?如何实现无感刷新?
Token过期了会怎么样:
首先服务器是没有记忆的, 浏览器向服务器发送请求; 服务器是不知道你是谁的, 所以就需要携带token值.
token就相当于一把钥匙, 服务器就像一张大门; 只有钥匙才能开门.
如果token过期了, 浏览器向服务器发送请求; 一般在请求拦截器里面就会返回一个401的状态码, 然后会清除用户信息, 让用户重新登录, 重新获取token值.
因为基于安全方面的考虑, token值的失效期后端通常会设置在2小时, 若果用户长时间的在当前页面停留, 那就会每隔两小时就要重新登录一次(用户体验性极差).
实现无感刷新:
用户在首次进行登录验证的时候, 服务器会返回Access Token, Id Token和Refresh Token; 我们需要做的就是将Refresh Token好好的保存到本地, 因为Refresh Token跟用户的账号密码一样重要. Refresh Token能够让用户一直保存登录的状态.
因为Access Token和Id Token失效期是非常短的, 用户发送请求时, 请求拦截器发现token已经失效; 那么Refresh Token就会发送请求获取新token, 替换掉失效的token, 直接使用新的token, 最后将失败的请求发出去.
这样可以缩短 AccessToken 的过期时间保证安全,同时又不会因为频繁过期重新要求用户登录.
补充:
- 在access token添加用户身份信息,可能导致用户信息泄露, 因为每次接口请求都携带access token,其payload部分的用户信息是可解析的,相当于是明文的.
- access token目的是用于接口访问的凭证,如果同时包含用户信息的话,功能就不分离了.
- 使用idToken替换userinfo endpoint获取用户信息.
- 某些场景,如只需要用户登录认证并获取用户信息,而不必调用Resource Server的其他API;那么这种场景只需要返回idToken,accessToken将不必返回.
- idToken只用于用户身份信息认证,并不能用户接口调用的凭证.
2. 一个页面从输入URL到页面加载显示完成, 这个过程中发生了什么?
浏览器
查找
域名对应的IP地址
(DNS 查询:浏览器缓存->系统缓存->路由器缓存->ISP DNS 缓存->根域名服务器)浏览器
向 Web 服务器
发送
一个HTTP 请求
(TCP三次握手)服务器
301重定向
(从 http://example.com 重定向到 http://www.example.com)浏览器
跟踪
重定向地址
,请求另一个带 www 的网址服务器
处理请求
(通过路由读取资源)服务器
返回
一个HTTP 响应
(报头中把 Content-type 设置为 'text/html')浏览器
进 DOM 树构建
浏览器
发送请求获取
嵌在 HTML 中的资源
(如图片、音频、视频、CSS、JS等)浏览器
显示完成页面
浏览器
发送异步请求
3. 什么情况下会出现margin塌陷, 如何解决?
外边距塌陷共有两种情况:
- 第一种情况:两个同级元素,垂直排列,上面的盒子给 margin-bottom 下面的盒子给 margin-top,那么他们两个的间距会重叠,以大的那个计算。解决这种情况的方法为:两个外边距不同时出现.
- 第二种情况:两个父子元素,内部的盒子给 margin-top,其父级也会受到影响,同时产生上边距,父子元素会进行粘连.
解决方案:
1、为父盒子设置 border,添加 border 后父子盒子就不是真正意义上的贴合(可以设置成 透明:border:1px solid transparent);
2、为父盒子添加 overflow:hidden;
3、为父盒子设定 padding 值;
4、为父盒子添加 position:fixed;
5、为父盒子添加 display:table;
6、利用伪元素给父元素的前面添加一个空元素
.father::before {
content:'';
display:table;
}
4. 请写至少三种数组去重的方法?(原生js)
//利用filter
function unique(arr) {
return arr.filter(function(item, index, arr) {
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item, 0) === index;
})
}
var arr = [1,1,'true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]
console.log(unique(arr))
//利用ES6 Set去重(ES6中最常用)
function unique (arr) {
return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]
console.log(unique(arr))
//利用for嵌套for,然后splice去重(ES5中最常用)
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1)
j--
}
}
}
return arr
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]
console.log(unique(arr))
5. for in 和 for of 的区别?
for in
遍历的是数组的索引(即键名),而for of
遍历的是数组元素值
for in
可以得到对象的key
或数组、字符串的下标
for of
不能直接遍历对象, 可以先通过 Object.keys
得到对象的键再获取值