专业汉语词典知识平台,分享汉字词语知识、历史文学知识解答!

励北网
励北网

_window.onerror 跨域资源错误处理,error事件怎么处理

来源:小易整编  作者:小易  发布时间:2023-02-25 05:07
摘要:_window.onerror跨域资源错误处理,error事件怎么处理触发的error 事件,可以在顶级事件处理(GlobalEventHandlers)中处理。并且当捕获到error事件时,window 会ErrorEvent接口的err...

_window.onerror 跨域资源错误处理,error事件怎么处理

触发的 error  事件,可以在顶级事件处理(GlobalEventHandlers)中处理。并且当捕获到 error 事件时,window  会 ErrorEvent 接口的 error 事件,ErrorEvent 原型上的属性全是只读的。通常来讲,可以通过 _window.onerror 或 window.addEventListener('error') 来监听错误异常。下面,将从源头开始,从触发时机,到异常捕获再到异常处理,进行一些详细操作。

触发时机

  • JavaScript 运行时错误,例如语法错误(比如数组方法用在了字符串上,使用未定义的变量)

  • 资源加载错误,资源加载错误的error事件并不会冒泡到 window,正确做法应该在具体的资源上监听 error 事件。

不同域的脚本错误

当加载自不同域的脚本中发生语法错误时,为避免信息泄露(参见bug 363897),语法错误的细节将不会报告,而代之简单的”Script error.”。(MDN)

MDN 已经描述的很清楚,当在不同域发生脚本错误时,代码并不能获取详细的错误堆栈。只会获取 message 为 Script error. 的消息。下面我们来复现一个案例。

不同域脚本错误案例

新建以下文件

_window.onerror 跨域资源错误处理,error事件怎么处理

index.html 作为测试页面,分别引入 a.js 和 c.js

_window.onerror 跨域资源错误处理,error事件怎么处理

在b.js暴露出一个方法,为了全局访问,将其挂载到window对象上。

_window.onerror 跨域资源错误处理,error事件怎么处理

c.js 暴露出一个对象,并且对象存在一个 hello 的方法,方法中引入了一个未定义的变量(随意书写几个字符进去)。将 c.js 复制一份,加入将 C 方法改为 B, 并上传到远程CDN,作为不同域的资源来调用。

在 a.js 中实例化 B,C 对象,监听按钮点击事件,并分别执行 hello 方法。

_window.onerror 跨域资源错误处理,error事件怎么处理

为项目起一个简单的服务器

http-server

打开默认的 8080 端口,分别点击两个按钮。查看打印的日志。

远程 js 中的错误如下图,可以看到,ErrorEvent 对象中的 message 只有 Script error. 并且行数,列数,filename 等信息都没有展示。而Chrome devtool 中却展示了详细的信息。这是为了避免信息泄露而被浏览器屏蔽。

_window.onerror 跨域资源错误处理,error事件怎么处理

反之,查看本地加载的 js, 截图如下。有详细的错误信息。

_window.onerror 跨域资源错误处理,error事件怎么处理

以上就是不同域的列子。下面解释为什么会产生安全隐患。

从 _window.onerror 窃取用户信息

很多网站的登录页面,或者维护用户状态的接口都会返回用户信息。如果使用 script 标签加载一个不是 text/javascript 的文件,就会触发 _window.onerror 事件。我们来进行一次模拟。假如我们有一个存放用户数据的文件,叫 user.json, 这里返回一些数据

name=beace

我们尝试使用 script 标签来加载这个文件。在上面的 index.html 中添加 script 标签。

<script src="./user.json"></script>

刷新浏览器可以看到

_window.onerror 跨域资源错误处理,error事件怎么处理

_window.onerror 监听到了用户数据,并返回了关键信息,可以通过 event.message 获取用户名“beace”。这是同域下进行的模拟,若不同域,只能得到 Script error. 字符串。

更加详细的描述可以参考这几篇文章

https://bugzilla.mozilla.org/show_bug.cgi?id=363897

https://blog.jeremiahgrossman.com/2006/12/i-know-if-youre-logged-in-anywhere.html

https://blog.jeremiahgrossman.com/2006/12/i-know-if-youre-logged-in-anywhere.html

需要跨域

有时候,我们的静态资源部署在独立的 CDN 域名上,可能与主域并不相同。如果我们需要选择相信跨域加载的资源,并且希望捕获它的错误,就需要在 script 上增加 crossorigin 属性。在这里多说一句,原则上来讲,跨域是浏览器为了安全做的事情,任何形式的跨域都需要后端程序来配合。因此,需要服务端增加请求头 Access-Control-Allow-Origin: http://foo.example 。这样就可以获取完整的错误堆栈了。

将 b.js 放到当前目录下,接下来,我们同过 localhost 访问和 127.0.0.1 的方式来作为跨域的场景,修改 index.html 引入 b.js

<script src="http://127.0.0.1:8080/b.js" crossorigin></script>

重启 http-server ,增加 cors 参数

http-server --cors

可以看到 b.js 返回头增加了 Access-Control-Allow-Origin 参数。

_window.onerror 跨域资源错误处理,error事件怎么处理

这样再次点击按钮,就可以发现两种资源加载的错误都可以拿到详细的错误信息了。

_window.onerror 跨域资源错误处理,error事件怎么处理



本文地址:百科问答频道 https://www.neebe.cn/wenda/903393.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!


百科问答
小编:小易整编
相关文章相关阅读
  • 周排行
  • 月排行
  • 年排行

精彩推荐