JavaScript 异常处理 详解(3)

接下来我们还需要实现一套完整的机制,保证这些由 scheduleRemoteScript 根据地址下载回来的文件内容和由 scheduleInlineScript 直接获取到的代码能够按照正确的顺序一个接一个地执行。详细的代码我就不在这里给出了,大家有兴趣可以自己去实现。

行号反查

通过 CORS 获取内容再把代码注入页面能够突破安全限制,但会引入一个新的问题,那就是行号冲突。原本通过 error.script 可以定位到唯一的脚本文件,再通过 error.line 可以定位到唯一的行号。现在由于都是页面内嵌的代码,多个 <script> 标签并不能通过 error.script 来区分,然而每一个 <script> 标签内部的行号都是从 1 算起的,结果就导致我们无法利用异常信息定位错误所在的源代码位置。

为了避免行号冲突,我们可以浪费一些行号,使得每一个 <script> 标签中有实际代码所使用的行号区间互相不重叠。举个例子来说,假设每个 <script> 标签中的实际代码都不超过 1000 行,那么我可以让第一个 <script> 标签中的代码占用第 1–1000 行,让第二个 <script> 标签中的代码占用第 1001–2000 行(前面插入 1000 行空行),第三个 <script> 标签种的代码占用第 2001–3000 行(前面插入 2000 行空行),以此类推。然后我们使用 data-* 属性记录这些信息,便于反查。

复制代码 代码如下:


<script
 data-src=""
 data-line-start="1"
>
 // code for step 1
</script>
<script data-line-start="1001">
 // '\n' * 1000
 // code for step 2
</script>
<script
 data-src=""
 data-line-start="2001"
>
 // '\n' * 2000
 // code for step 3
</script>


 
经过这样处理后,如果一个错误的 error.line 是 3005 的话,那意味着实际的 error.script 应该是 'https://cdn.com/step3.js',而实际的 error.line 则应该是 5。我们可以在之前提到的 reportError 函数里面完成这项行号反查工作。

当然,由于我们没办法保证每一个脚本文件只有 1000 行,也有可能有些脚本文件明显小于 1000 行,所以其实不需要固定分配 1000 行的区间给每一个 <script> 标签。我们可以根据实际脚本行数来分配区间,只要保证每一个 <script> 标签所使用的区间互不重叠就可以了。

crossorigin 属性

浏览器对于不同源的内容进行的安全限制当然不仅限于 <script> 标签。既然 XMLHttpRequest 可以通过 CORS 来突破这个限制,为什么直接通过标签引用的资源就不可以呢?这当然是可以的。

针对 <script> 标签引用不同源脚本文件的限制同样作用于 <img> 标签引用不同源图片文件。如果一个 <img> 标签是不同源的话,一旦在 <canvas> 绘图时用到了,该 <canvas> 将变为只写状态,保证网站不能通过 JavaScript 窃取未授权的不同源图片数据。后来 <img> 标签通过引入 crossorigin 属性解决了这个问题。如果使用 crossorigin="anonymous",则相当于匿名 CORS;如果使用 `crossorigin=“use-credentials”,则相当于带认证的 CORS。

既然 <img> 标签能这样做,为什么 <script> 标签就不能这样做?于是浏览器厂商就为 <script> 标签加入了同样的 crossorigin 属性用于解决上述安全限制问题。现在 Chrome 和 Firefox 对这个属性的支持是完全没有问题的。Safari 则会把 crossorigin="anonymous" 当做 crossorigin="use-credentials" 处理,结果是如果服务器只支持匿名 CORS 则 Safari 会当做认证失败。由于 CDN 服务器出于性能的考虑被设计为只能返回静态内容,不可能动态的根据请求返回认证 CORS 所需的 HTTP Header,Safari 相当于不能利用此特性来解决上述问题。

总结

JavaScript 异常处理看起来很简单,跟其它语言没什么区别,但真的要把异常都捕获了然后对属性做分析,其实还不是那么容易的事情。现在尽管有一些第三方服务提供捕获 JavaScript 异常的类 Google Analytics 服务,但如果要弄明白其中的细节和原理还是必须自己亲手做一次。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgfxxx.html