iframe如何发送请求_如何优雅地处理前端异常?

2023-11-15

69a72b834f4451112dcda7bee7d712fa.gif

前端一直是距离用户最近的一层,随着产品的日益完善,我们会更加注重用户体验,而前端异常却如鲠在喉,甚是烦人。

一、为什么要处理异常?

异常是不可控的,会影响最终的呈现结果,但是我们有充分的理由去做这样的事情。

  • 增强用户体验;

  • 远程定位问题;

  • 未雨绸缪,及早发现问题;

  • 无法复线问题,尤其是移动端,机型,系统都是问题;

  • 完善的前端方案,前端监控系统;

对于 JS 而言,我们面对的仅仅只是异常,异常的出现不会直接导致 JS 引擎崩溃,最多只会使当前执行的任务终止。

二、需要处理哪些异常?

对于前端来说,我们可做的异常捕获还真不少。总结一下,大概如下:

  • JS 语法错误、代码异常

  • AJAX 请求异常

  • 静态资源加载异常

  • Promise 异常

  • Iframe 异常

  • 跨域 Script error

  • 崩溃和卡顿

下面我会针对每种具体情况来说明如何处理这些异常。

三、Try-Catch 的误区

try-catch 只能捕获到同步的运行时错误,对语法和异步错误却无能为力,捕获不到。

  1. 同步运行时错误:

try {  let name = 'jartto';  console.log(nam);} catch(e) {  console.log('捕获到异常:',e);}

输出:

捕获到异常:ReferenceError: nam is not defined    at :3:15

2.不能捕获到语法错误,我们修改一下代码,删掉一个单引号:

try {  let name = 'jartto;  console.log(nam);} catch(e) {  console.log('捕获到异常:',e);}

输出:

Uncaught SyntaxError: Invalid or unexpected token

不过语法错误在我们开发阶段就可以看到,应该不会顺利上到线上环境。

3.异步错误

try {setTimeout(() => {undefined.map(v => v);}, 1000)} catch(e) {console.log('捕获到异常:',e);}

我们看看日志:

Uncaught TypeError: Cannot read property 'map' of undefinedat setTimeout (:3:11)

并没有捕获到异常,这是需要我们特别注意的地方。

四、window.onerror 不是万能的

当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror()。

/*** @param {String} message 错误信息* @param {String} source 出错文件* @param {Number} lineno 行号* @param {Number} colno 列号* @param {Object} error Error对象(对象)*/window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});}

1.首先试试同步运行时错误

window.onerror = function(message, source, lineno, colno, error) {// message:错误信息(字符串)。// source:发生错误的脚本URL(字符串)// lineno:发生错误的行号(数字)// colno:发生错误的列号(数字)// error:Error对象(对象)console.log('捕获到异常:',{message, source, lineno, colno, error});}Jartto;

可以看到,我们捕获到了异常:

ef652a3d8feb587056e5380e35f6c335.png

2.再试试语法错误呢?

window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});}let name = 'Jartto

控制台打印出了这样的异常:

Uncaught SyntaxError: Invalid or unexpected token

什么,竟然没有捕获到语法错误?

3.怀着忐忑的心,我们最后来试试异步运行时错误:

window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});}setTimeout(() => {Jartto;});

控制台输出了:

捕获到异常:{message: "Uncaught ReferenceError: Jartto is not defined", source: "http://127.0.0.1:8001/", lineno: 36, colno: 5, error: ReferenceError: Jartto is not definedat setTimeout (http://127.0.0.1:8001/:36:5)}

4.接着,我们试试网络请求异常的情况:

window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});return true;}

我们发现,不论是静态资源异常,或者接口异常,错误都无法捕获到。

补充一点:window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,否则即使是知道异常的发生控制台还是会显示 Uncaught Error: xxxxx

window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});return true;}setTimeout(() => {Jartto;});

控制台就不会再有这样的错误了:

Uncaught ReferenceError: Jartto is not definedat setTimeout ((index):36)

需要注意:

onerror 最好写在所有 JS 脚本的前面,否则有可能捕获不到错误;

onerror 无法捕获语法错误;

到这里基本就清晰了:在实际的使用过程中,onerror 主要是来捕获预料之外的错误,而 try-catch则是用来在可预见情况下监控特定的错误,两者结合使用更加高效。

问题又来了,捕获不到静态资源加载异常怎么办?

五、iframe 异常

对于 iframe 的异常捕获,我们还得借力 window.onerror:

window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});}

一个简单的例子可能如下:

window.frames[0].onerror = function (message, source, lineno, colno, error) {console.log('捕获到 iframe 异常:',{message, source, lineno, colno, error});return true;};

六、Script error

一般情况,如果出现 Script error 这样的错误,基本上可以确定是出现了跨域问题。这时候,是不会有其他太多辅助信息的,但是解决思路无非如下:

跨源资源共享机制( CORS ):我们为 script 标签添加 crossOrigin 属性。

或者动态去添加 js 脚本:

const script = document.createElement('script');script.crossOrigin = 'anonymous';script.src = url;document.body.appendChild(script);

七、崩溃和卡顿

卡顿也就是网页暂时响应比较慢, JS 可能无法及时执行。但崩溃就不一样了,网页都崩溃了,JS都不运行了,还有什么办法可以监控网页的崩溃,并将网页崩溃上报呢?

崩溃和卡顿也是不可忽视的,也许会导致你的用户流失。

1.利用 window 对象的 load 和 beforeunload 事件实现了网页崩溃的监控。

window.addEventListener('load', function () {sessionStorage.setItem('good_exit', 'pending');setInterval(function () {sessionStorage.setItem('time_before_crash', new Date().toString());}, 1000);});window.addEventListener('beforeunload', function () {sessionStorage.setItem('good_exit', 'true');});if(sessionStorage.getItem('good_exit') &&sessionStorage.getItem('good_exit') !== 'true') {/*insert crash logging code here*/alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'));}

2.基于以下原因,我们可以使用 Service Worker 来实现网页崩溃的监控:

Service Worker 有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker 一般情况下不会崩溃;

Service Worker 生命周期一般要比网页还要长,可以用来监控网页的状态;

网页可以通过 navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 发送消息。

八、错误上报

1.通过 Ajax 发送数据

因为 Ajax 请求本身也有可能会发生异常,而且有可能会引发跨域问题,一般情况下更推荐使用动态创建 img 标签的形式进行上报。

2.动态创建 img 标签的形式

function report(error) {let reportUrl = 'http://jartto.wang/report';new Image().src = `${reportUrl}?logs=${error}`;}

收集异常信息量太多,怎么办?实际中,我们不得不考虑这样一种情况:如果你的网站访问量很大,那么一个必然的错误发送的信息就有很多条,这时候,我们需要设置采集率,从而减缓服务器的压力:

Reporter.send = function(data) {// 只采集 30%if(Math.random() < 0.3) {send(data) // 上报错误信息}}

采集率应该通过实际情况来设定,随机数,或者某些用户特征都是不错的选择。

八、总结

回到我们开头提出的那个问题,如何优雅的处理异常呢?

1.可疑区域增加 Try-Catch

2.全局监控 JS 异常 window.onerror

3.全局监控静态资源异常 window.addEventListener

4.捕获没有 Catch 的 Promise 异常:unhandledrejection

5.VUE errorHandler 和 React componentDidCatch

6.监控网页崩溃:window 对象的 load 和 beforeunload

7.跨域 crossOrigin 解决

其实很简单,正如上文所说:采用组合方案,分类型的去捕获异常,这样基本 80%-90% 的问题都化于无形。

推荐阅读:

通过分析Github众多前端代码库,总结出来的前端代码书写规范

【前端艺术】HTML5 Canvas和jQuery实时动态天气预报

前端设计开发常用命名规则

觉得文章不错,点下在看e00e8366bfe0461c7cff25e7411796b5.gif

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iframe如何发送请求_如何优雅地处理前端异常? 的相关文章

  • Qt5下串口编程中“QIODevice::write (QSerialPort): device not open”问题的分析处理总结

    一 实现功能说明 在主窗口中先配置好串口并 打开串口 在菜单中点击 测量 子窗口 进入子窗口画面 点击子窗口的 测量 按钮 实现读取传感器指令的数据发送 二 程序说明 主窗口 1 MainWidget h 定义类MainWidget 构造函
  • 数据库行锁

    数据库行锁 仅作为笔记 码字不易 转载请标明出处 文章目录 数据库行锁 前言 一 数据库行锁 前言 仅作为笔记 一 数据库行锁 两阶段锁 在 InnoDB 事务中 锁是在需要的时候才加上的 但并 是 需要 就立刻释放 而是要等到事务结束时才
  • Mongdb查询 - 比较运算符、逻辑运算符、$type、游标

    目录 一 比较运算符 Mongo查询条件和SQL查询对照表 比较运算符示例 二 逻辑操作符 逻辑操作符示例 not用法 and用法 eq用法 or用法 三 type操作符 四 文档游标 基本操作 游标的执行顺序 limit skip sor
  • CGAL的编译与配置

    CGAL的编译与配置 网上已经有一些配置的步骤 但是在具体配置过程中 发现有很多问题 折腾了两天后终于配置成功 在此做更详细的记录 准备 CGAL CGAL4 7和CGAL4 9的库 分别编译成功了 BOOST boost1 59的版本 C
  • 2022经典前端面试题大全 h5 +cs +js

    一 页面布局 三栏布局 题目 假设高度已知 请写出三栏布局 其中左栏 右栏宽度各为 300px 中间自适应 解答 可以有很多种布局方式 这里列出五种 float布局 absolute布局 flex布局 table布局 grid布局 代码如下
  • mybatis设计大接口的坑以及做法

    先说一些注意事项 1 注 mybatis一个mapper java文件只能对应一个mapper xml文件 所以不能一个mapper java对应两个xml 一个默认的 一个自己拓展的 2 注 如果表中有字段是text selectByEx
  • 可视化笔记1--matplotlib 常见图形绘制1

    可视化笔记1 matplotlib 常见图形绘制1 最近需要使用python实现部分数据的可视化 于是简单学习了下matplotlib绘图功能 基本包括 散点图 折线图 条形图 直方图 饼状图 箱形图等几种常用图形的绘制方式 相应学习笔记分
  • 解决谷歌浏览器无法自动播放HTML文件的声音和视频问题的方法

    首先 先检测一下浏览器是否能支持自动播放 点击下方链接进行检测 https video dev github io can autoplay 本人检测的谷歌浏览器结果是 结果显示 谷歌浏览器不能支持有声自动播放视频和音频 包括内联的视频 但
  • 密码学研究重点

    密码学涵盖了认证 数字签名以及更多基本的安全功能 密码学涉及领域及其宽广 包括计算机安全 高等数学 经济学 量子物理学 民法和刑法 统计学 芯片设计 软件优化 政治 用户界面设计等 0x01 密码学重要性 密码学本身没有价值 必须作为一个系
  • tessract-ocr文本识别系统网页搭建【PHP】

    tessract ocr文本识别系统网页搭建 下面是我搭的网站 OCR文本识别系统 在安装后tesstact ocr后 我找到了一个利用php调用ocr接口的方法 在github上有这样一个项目 https github com thiag
  • 为何boss上的HR要了简历就不回复了?

    不止一个小伙伴在微信上问过我这个问题 今天就来跟大家分享一下出现这种现象的原因 并给我认为在boss上的正确打招呼方式 废话不多说 开始今天的主题分享 出现这一现象一般有以下几种原因 1 简历与岗位需求不匹配 这很好理解 其实就是别人没看上
  • K8s中的Deployment

    Deployment是kubernetes在1 2版本中引入的新概念 用于更好的解决Pod的编排问题 为此 Deployment在内部使用了ReplicaSet来实现目的 我们可以把Deployment理解为ReplicaSet的一次升 级
  • 【精华】批量修改文件夹中的文件名

    转载自 批量修改文件名 原文地址如下 http t csdn cn tGsfz 1 在所需批量修改文件名的文件夹内新建一个改 txt文件 并在新建的txt文件中输入dir gt 1 txt 2 修改新建的改 txt文件的后缀名为 bat 3
  • 虚拟机Ubuntu20.04一招解决无法连接网络问题

    虚拟机Ubuntu20 04一招解决无法连接网络问题 网上试了很多方法都没解决 最后一招解决 简单的网上一堆教程自己找下 此教程适合解决不了的同学 第一步 先关闭虚拟机的ubuntu系统 然后虚拟机 gt 设置 gt 网络适配器 选择NAT
  • 泛型是实体类的集合,根据某一字段排序

    举例 List
  • IDEA将web项目打包成war包

    目录 通用的方式打包 maven方式打包 eclipse版本 https blog csdn net weixin 45859844 article details 119965820 如果要到服务器部署项目 可能需要将项目打成war包 放
  • 程序员必备的思维能力:结构化思维

    在日常工作中 我们时常会碰到这样的情况 有的人讲一件事情的时候逻辑非常混乱 说了很多事情的罗列 却说不到重点 有的人写代码 本身的业务逻辑并没有多复杂 但呈现出的代码却像一堆线团 混乱不堪 无法理解 这些都是典型的缺少结构化思维的表现 导致
  • 挖矿病毒解决

    1 进程 cpu 100 watchdog 2 解决 tmp netstat 矿池 鱼池 sup 进程 文件主程序 crontab l 计划任务 分析脚本 3 如何进来的 web日志 log4j 命令 漏洞 docker yam fastj

随机推荐

  • Mathematica 有关向量与矩阵的函数

    下面是Mathematica中常用的关于向量和矩阵的函数
  • MySQL添加用户、删除用户、授权及撤销权限

    一 创建用户 mysql gt insert into mysql user Host User Password values localhost test password 1234 这样就创建了一个名为 test 密码为 1234 的
  • JAVA并发-Monitor简介

    什么是Monitor 1 Monitor是一种用来实现同步的工具 2 与每个java对象相关联 即每个java对象都有一个Monitor与之对应 3 Monitor是实现Sychronized 内置锁 的基础 Monitor的基本结构是什么
  • 十问十答

    凯云科技 今年六月 我们迎来了异常炎热的夏季 炎炎烈日也抵挡不了我们前进的步伐 上海 北京都留下了凯云的身影 两场展会 一场论坛 我们也得到了来自客户的高度认可 对此 小编特意整理了关于核心软件ETest的十问十答 为还心存疑惑的小伙伴们答
  • idea配置两个git源地址步骤并合并代码

    最近做项目迁移 把原来的gitlab上的代码迁移到了另一个gitlab仓库汇总 更换了git源地址 这样需要把原来项目的代码合并到新的gitlab仓库中 添加git源地址
  • Oracle数据库表的约束

    Oracle数据库约束类型主要有以下几个 primary key 主键约束 foreign key 外键约束 check 检查约束 unique 唯一约束 not null 非空约束 alter table table name add c
  • TypeScript实现八大排序与搜索算法

    前言 我们在页面上渲染数据时 通常会根据特定规则来对数据进行一个排序 然后再将其渲染到页面展示给用户 那么对数据进行排序有很多种方式 哪一种效率高 哪一种稳定性好 那一种占用内存小 本文将详解经典的八大排序算法以及三种搜索算法 并用Type
  • 【排错日记】PageHelper插件的默认分页参数

    现象 没有写如下代码 执行的结果却被分页显示了 PageHelper startPage listParam getPageNum listParam getPageSize 源码分析 调用方法判断是否需要进行分页 如果不需要 直接返回结果
  • k8s 启动探针生存探针&就绪探针

    目录 k8s 启动探针 存活探针 就绪探针 存活 就绪探针的区别 探针处理程序和结果 启动探针 存活探针 livenessProbe exec livenessProbe httpget livenessProbe tcp 就绪探针 k8s
  • 【总结】NPU/CPU/GPU 傻傻分不清?

    本文主要解答以下问题 NPU是新玩意儿吗 芯片里面的CPU GPU NPU究竟是什么 它们是怎么工作的 引言 中国首款嵌入式NPU诞生 6月20日 中星微 数字多媒体芯片技术 国家重点实验室在京宣布 中国首款嵌入式NPU 神经网络处理器 芯
  • AWTRIX像素屏时钟搭建

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 AWTRIX像素屏时钟搭建 前言 一 AWTRIX是什么 二 AWTRIX像素屏时钟搭建步骤 1 材料准备 2 ESP8266固件刷写 3 接线方式 4 手机端配网 4 服务
  • 2022中山大学计算机技术专硕考研初试、复试经验帖

    2022年中山大学计算机技术专硕考研初试 复试经验帖 个人简介 推荐几个我自己感觉对考研非常有帮助的小助手吧 可以帮助节省时间 考研时间规划总览 初试篇 数学 英语 政治 408 复试篇 如果觉得有帮助的话可以点个收藏后续会修改和增加内容
  • shell判断程序是否运行,守护进程

    一 需求 服务部署在linux上 要求服务器上的服务可以一直保持正常运行 二 问题 在linux上部署的微服务 不知道什么原因过一段时间就自己停掉了 无法启动 三 解决办法 添加angle守护进程 通过定时执行脚本来判断程序是否运行 若不是
  • 微信小程序获取微信步数

    获取步数授权 获取用户微信运动步数的前提是用户授权小程序访问他的微信运动数据 微信对用户隐私有严格的控制 任何涉及用户隐私的敏感数据都需要用户同意后小程序才能获取 只有当用户点击 允许 后 小程序才能获取用户的微信运动数据 小程序的用户授权
  • Vue组件通信方式详解(全面版)

    在Vue应用开发中 组件通信是一个重要的话题 不同的组件可能需要在不同的情况下进行数据传递和交互 Vue提供了多种方式来实现组件通信 每种方式都有其适用的场景 本文将详细介绍Vue中实现组件通信的各种方式 并为每种方式提供通俗易懂的代码示例
  • Java并发编程实战——并发容器之ConcurrentHashMap(JDK 1.8版本)

    文章目录 ConcurrentHashmap简介 从关键属性及类上来看ConcurrentHashMap的结构 put 方法管中窥豹 CAS关键操作 ConcurrentHashmap简介 在使用HashMap时在多线程情况下扩容会出现CP
  • Python3,10行代码竟然让URL变短了,没想到还可以这么玩。

    让URL变短的方法 1 引言 2 代码实战 2 1 定义 2 2 常用函数 2 3 示例 3 总结 1 引言 小屌丝 鱼哥 有没有什么方法 能让url变短一点 小鱼 我去 url怎么惹你了 你让它变短 小屌丝 没有了 我就是觉得url太长了
  • 西门子fifo_西门子官方开发的LGF库全中文解读,重磅推荐

    Hello 欢迎大家来到 西家大书 这里可能是西门子最内部的知识分享平台 众所周知 TIA Portal STEP 7 具有一个功能强大的LGF全局库 它可以计算随机数 最大值 最小值 平均值 实现搜索功能 计算日出日落时间等等 但关于LG
  • @符号的用法

    代码中 符号有时候会在有些代码中遇到 其具体有什么作用呢 主要用法 限定作用 用来限定字符串 具体而言实际上就是表示字符串中的 字符不再认为是转义标志 而就是 符号本身 常见的用法是如果我们写一个文件所处的路径 比如 D 文本文件 路径下的
  • iframe如何发送请求_如何优雅地处理前端异常?

    前端一直是距离用户最近的一层 随着产品的日益完善 我们会更加注重用户体验 而前端异常却如鲠在喉 甚是烦人 一 为什么要处理异常 异常是不可控的 会影响最终的呈现结果 但是我们有充分的理由去做这样的事情 增强用户体验 远程定位问题 未雨绸缪