大家好,我是若川。欢迎加我微信 ruochuan12,长期交流学习。今天分享几个常见的前端防御性编程方案。点击下方卡片关注我,或者查看源码等系列文章。学习源码整体架构系列、年度总结、JS基础系列
关于前端防御性编程
我们大多数情况可能遇到过,后端的由于同时请求人数过多,或者数据量过大,又或者是因为异常导致服务异常,接口请求失败,然后前端出现白屏或者报错
还有一种情况,是前端自身写的代码存在一些缺陷,整个系统不够健壮,从而会出现白屏,或者业务系统异常,用户误操作等
那么,就出现了前端防御性编程
常见的问题和防范
1.最常见的问题:
uncaught TypeError: Cannot read property 'c' of undefined
出现这个问题最根本原因是:
当我们初始化一个对象obj为{}时候,obj.a这个时候是undefined.我们打印obj.a可以得到undefined,但是我们打印obj.a.c的时候,就会出现上面的错误。js对象中的未初始化属性值是undefined,从undefined读取属性就会导致这个错误(同理,null也一样)
如何避免?
js和ts目前都出现了一个可选链概念
,例如:
const obj = {};
console.log(obj?.b?.c?.d)
上面的代码并不会报错,原因是
?.
遇到是空值的时候便会返回undefined.
2.前端接口层面的错误机制捕获
前端的接口调用,一般都比较频繁,我们这时候可以考虑使用单例模式,将所有的axios请求都用一个函数封装一层。统一可以在这个函数中catch捕获接口调用时候的未知错误,伪代码如下:
function ajax(url,data,method='get'){const promise = axios[method](url,data)return promise.then(res=>{}).catch(error){//统一处理错误
}
}
那么只要发生接口调用的未知错误都会在这里被处理了
3.错误边界(Error Boundaries,前端出现未知错误时,展示预先设定的UI界面)
以React为例
部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。
错误边界是一种 React 组件,这种组件可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且,它会渲染出备用 UI,而不是渲染那些崩溃了的子组件树。错误边界在渲染期间、生命周期方法和整个组件树的构造函数中捕获错误。
使用示例:
class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}static getDerivedStateFromError(error) {// 更新 state 使下一次渲染能够显示降级后的 UIreturn { hasError: true };}componentDidCatch(error, errorInfo) {// 你同样可以将错误日志上报给服务器logErrorToMyService(error, errorInfo);}render() {if (this.state.hasError) {// 你可以自定义降级后的 UI 并渲染return <h1>Something went wrong.</h1>;}return this.props.children; }
}
注意
错误边界无法捕获以下场景中产生的错误:
事件处理(了解更多)
异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
服务端渲染
它自身抛出来的错误(并非它的子组件)
4.前端复杂异步场景导致的错误
这个问题可能远不止这么简单,但是大道至简,遵循单向数据流的方式去改变数据,例如:
//test.js
export const obj = {a:1,b:2
}//使用obj
import {obj} from './test.js';
obj.a=3;
当你频繁使用这个obj
对象时,你无法根据代码去知道它的改变顺序(即在某个时刻它的值是什么),而且这里面可能存在不少异步的代码,当我们换一种方式,就能知道它的改变顺序了,也更方便我们debug
例如:
//test.js
export const obj = {a:1,b:2
}
export function setObj (key,value) {console.log(key,value)obj[key] = value
}
这样,我们就做到了
5.前端专注“前端”
对于一些敏感数据,例如登录态,鉴权相关的。前端应该是尽量做无感知的转发、携带(这样也不会出现安全问题)
6.页面做到可降级
对于一些刚上新的业务,或者有存在风险的业务模块,或者会调取不受信任的接口,例如第三方的接口,这个时候就要做一层降级处理,例如接口调用失败后,剔除对应模块的展示,让用户无感知的使用
7.巧用loading和disabled
用户操作后,要及时loading和disabled确保不让用户进行重复,防止业务侧出现bug
8.慎用innerHTML
容易出现安全漏洞,例如接口返回了一段JavaScript脚本,那么就会立即执行。此时脚本如果是恶意的,那么就会出现不可预知的后果,特别是电商行业,尤其要注意。
最近组建了一个江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你进群。
················· 若川出品 ·················
今日话题
运营公众号以来,常有人识别二维码加群打广告或者抢红包,比如发支付宝口令红包会被分享给别人抢,关键就一块钱,另外还有搞抽奖活动也有非前端的人参与抽奖,有时候怀疑他们有团队,专门撸羊毛。欢迎分享、收藏、点赞、在看我的公众号文章~
一个愿景是帮助5年内前端人走向前列的公众号
可加我个人微信 ruochuan12,长期交流学习
推荐阅读
我在阿里招前端,我该怎么帮你?(现在还能加我进模拟面试群)
如何拿下阿里巴巴 P6 的前端 Offer
点击上方卡片关注我,或者查看源码等系列文章。
学习源码整体架构系列、年度总结、JS基础系列