1、什么是 options 请求?
在正式跨域之前,浏览器会根据需要发起一次预检请求(即 options 请求),用来让服务端返回允许的方法(如 get、post)
浏览器会发出两种请求:
(1)简单请求(一次请求,无 预检)

(2)非简单请求(先 预检,通过后,正式发出请求)

区别:预检不会携带 cookie,正式请求会携带 cookie 和 参数。
详情请参考:https://www.jianshu.com/p/5cf82f092201
2、path.join() 和 path.resolve() 的区别(Nodejs)
path.join() :连接参数,返回相对路径
path.join('a', 'b', 'c') // 返回 'a\b\c'
path.join('/a/b','c') // 返回 'a\b\c'
path.join('') // 返回 '.',表示当前工作目录
path.resolve(): 连接参数,返回绝对路径
path.resolve('/a/b', 'c') // 返回 'F:\a\b\c'
path.resolve('') // 返回 F:\ES6Test
path.resolve('a','b','c') // 返回 F:\ES6Test\a\b\c
3、了解过 react-router 内部实现机制吗?
核心机制:实现了 URL(对应 location 对象) 和 UI(对应 React 的 components 组件) 的同步。
也就是 对象location 和 组件components 的同步。
同步的过程:
(1)点击 <Link/>
组件,<Link/>
组件会渲染为 HTML 标签 <a>
,它的 to、query、hash 属性会被 组合在一起 并渲染为 href
属性(虽然 Link 被渲染为超链接,但在内部实现上使用脚本拦截了浏览器的默认行为)
(2)然后调用了 history.pushState()
方法(注意,该 history 是 history 包里面的 create*History 方法创建的对象,不是 window.history 对象,尽管它们有些 API 相同)
(3)在调用 history.pushState() 的同时,会将 history.pushState() 的参数传输到 createLocation() 方法中,该方法返回一个 location 对象
(4)React-router 会将上述 location 对象作为参数传入到 TransitionTo()
方法中,该方法返回一个 新的 location,然后调用 window.location.hash 或者 window.history.pushState() (注意:尽管 API 相同,但不是 H5 的history)修改了应用的 URL
同时会触发history.listen 中注册的事件监听器。
(5)在得到了新的 location 对象后,React-router 的 matchRoutes()
方法会匹配出Route 组件树中与当前 location 对象匹配的一个子集,并且得到 nextState 对象
(6)在 Router 组件的 componentWillMount 生命周期方法中调用了 history.listen(listener) 方法。
listener 会在上述 matchRoutes 方法执行成功后执行listener(nextState)
(7)接下来执行 this.setState(nextState) 就可以重新渲染 Router 组件(修改 UI)
到这里,app 就完成了点击 Link 组件到页面刷新的全过程
注:原文表达模糊,简单点就是:点击 link -> 得到 location -> 调用 window.history.pushState() ->修改 url -> 根据 location 和 componentTree 算法匹配得到 nextState -> 在 componentWillMount 中执行 this.setState(nextState) ->重新渲染 UI
参考:
React-router路由基本原理(https://blog.csdn.net/leviscar/article/details/81878677)
react-router原理(https://blog.csdn.net/qq_36223144/article/details/83247008)
React Router 中文文档(https://react-guide.github.io/react-router-cn/index.html)
react-router的实现原理(https://blog.csdn.net/tangzhl/article/details/79696055)
4、前端缓存的相关知识
前端缓存一般分为「强缓存」和「协商缓存」。
强缓存:一定时间期限内,只使用本地缓存。
当设置 http 请求头的 Cache-Control 的值为 "public, max-age=xxx" 后,在 {max-age} 秒内再次访问该资源,不会向服务器发起请求,而是使用本地缓存。
缺点:当发布新版本后,如果后台接口同步更新,就直接 GG。
协商缓存:每次向服务器验证缓存的有效性。若有效,则使用 本地缓存,若无效,则使用 服务器的新数据。
缺点:耗费服务器资源。
最佳实践:尽可能使用「强缓存」,但在更新版本的时候,要修改静态资源的路径,这样就相当于第一次访问这些资源,从而完成刷新。
综上:
- HTML:使用「协商缓存」
- CSS、JS、图片:使用「强缓存」
5、什么是函数防抖和函数分流?
函数防抖:在一定时间范围内,多次触发事件,只调用一次事件处理函数。
生活示例:如果有人进电梯(触发事件),那电梯将在 5s 后关门(执行事件句柄),在 5s 内如果又有人进电梯了,又得再等 5s 再出发(重新计时)。
例:鼠标悬浮,获取后台数据,鼠标移出,不获取数据。
如果鼠标频繁移入移出,那么会频繁调用后台 api,导致资源浪费,可以使用 setTimeout 处理
function getData() {
console.log('a')
}
//鼠标移入,延迟获取数据
obj.onmousehover = function () {
//先清除之前的 setTimeout 的ID
clearTimeout(getData.timer)
//再设置延迟时间,防止频繁移入移出,调用 getData()
getData.timer = setTimeout(getData,500)
}
使用闭包保存 setTimeout 的 ID
function getData() {
console.log('a')
}
function saveTimerID(method,delay) {
let timer=null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
method.apply(context,args);
},delay);
}
}
obj.onmousemove = saveTimerID(getData,50);
函数分流:在「函数防抖」的前提下,再设置一个 时间阀值,比如 2s ,那么一旦触发时间,不管它 setTimeout 延迟多少, 2s 后一定会 触发。
生活示例:还是坐电梯,5s 内有人进来,就再等 5s,但是最多等 5 分钟,此时电梯门铃响起,必须关门。
例:还是鼠标悬浮、移出,但你不能老移入、移出、移入、移出,让其一直延后 调用函数时间,而是第一次移入后,开始计时,不管其中移入、移出多少次,1s 后必须调用后台 api,显示数据。
//method:getData(),delay:延迟调用的时间,mustRunDelay:必须执行的时间
function do(method, delay, mustRunDelay) {
let timer = null, args = arguments;
//start:第一次调用时间,now:最新的调用时间
let start = 0, now = 0
return function () {
let context = this;
now= Date.now();
if(!start){
start = now;
}
if(now - start >= mustRunDelay){
method.apply(context, args);
start = Date.now();
}else {
clearTimeout(timer);
timer = setTimeout(function () {
method.apply(context, args);
}, delay);
}
}
}
obj.onmousemove = do(getData, 50, 500);
欢迎关注公众号:gh_042070ae6d0a ,每周分享前端干货和生活感悟!
(完)
网友评论