一些用户向我们反馈,Fundebug的[JavaScript](https://docs.fundebug.com/notifier/javascript/)监控插件抓到了很多**Script error.**,然后行号和列号都是0...这就很尴尬了。

今天,我们来详细地解析一下`Script error.`,后续我们还会深度测试并且提供解决方法。

### 同源策略 (Same origin policy)

解释`Script error.`之前,我们先简单聊聊同源策略。摘自[MDN - Same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy):
> Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages.

所谓同源,就是指两个页面具有相同的协议、端口和主机(域名)。通过第三方加载的JavaScript脚本是不同源的。下面的表格简单列出了和`https://fundebug.com/app.js`是否同源的文件:

<style type="text/css">
code {
text-overflow:clip;/*文本裁切*/
white-space:nowrap;/*强制不换行*/
overflow:hidden;/*溢出隐藏*/
}
</style>

| 网址 | 是否同源 | 原因 |
| ---------------------------------- | --------: | :----: |
| `https://fundebug.com/vendor.js` | 是 | |
| `http://fundebug.com/vendor.js` | 否 | 协议不同 |
| `https://fundebug.com:8001/app.js` | 否 | 端口不同 |
| `https://docs.fundebug.com/nav.js` | 否 | 子域名不同 |
| `https://kiwenlau.com/totop.js` | 否 | 域名不同 |

没有同源策略的话,将会怎样?摘自[同源策略详解及绕过 - FreeBuf](http://www.freebuf.com/articles/web/65468.html):

> 假设你已经成功登录Gmail服务器,同时在同一个浏览器访问恶意站点(另一个浏览器选项卡)。没有同源策略,攻击者可以通过JavaScript获取你的邮件以及其他敏感信息,比如说阅读你的私密邮件,发送虚假邮件,看你的聊天记录等等。 如果将Gmail替换为你的银行帐户,问题就大条了。

### 为啥出现Script error. ?

为了提升网站的访问速度,我们通常都会将静态资源文件(css, image, javascript)放在第三方CDN。当这些从第三方加载的JavaScript脚本执行出错,因为违背了**同源策略**, 为了保证用户信息不被泄露,错误信息不会显示出来,取而代之只会返回一个`Script error.`。

暴露错误信息会怎样呢?摘自([Cryptic “Script Error.” reported in Javascript in Chrome and Firefox](http://stackoverflow.com/questions/5913978/cryptic-script-error-reported-in-javascript-in-chrome-and-firefox)):

> 假想你不小心访问了一个恶意网站,网页里面偷偷放入了一段JavaScript脚本 `<script src="cbcc.com/index.html">`,这段脚本指向你使用的某银行网站首页。虽然脚本会执行失败,但是错误信息却有可能泄露你的信息。如果你已经登录过该银行网站并且处于登录状态,那么错误信息可能为`'欢迎你 ....' is undefined`;如果你没有登录,那么错误信息可能是`'请登录...' is undefined`。 然后黑客就可以根据这些信息确定你使用的银行网站,并且伪造一个钓鱼网站来骗取钱财。

### 源码

[webkit源码](http://trac.webkit.org/browser/branches/chromium/648/Source/WebCore/dom/ScriptExecutionContext.cpp)如下:

```c++
bool ScriptExecutionContext::dispatchErrorEvent(const String& errorMessage,
int lineNumber,
const String& sourceURL)
{
EventTarget* target = errorEventTarget();
if (!target)
return false;
...
if (securityOrigin()->canRequest(targetUrl)) {
message = errorMessage;
line = lineNumber;
sourceName = sourceURL;
} else {
message = "Script error.";
sourceName = String();
line = 0;
}
...
}
```

可知,浏览器会判断所加载的资源url是否同源(`securityOrigin()->canRequest(targetUrl)`),如果不同源,则将错误消息隐藏,赋值为`Script error.`, 并且将行号设为0.

因此,如果我们从第三方CDN服务加载资源,如果出错的话,那么我们将只能看到`Script error.`。

### 错误复现

我们用一个简单的例子测试一下。下面是**index.html**,我们使用onerror来捕获错误。

```html
<!DOCTYPE html>
<html>
<head>
<title>Test Script error</title>
<script type="text/javascript">
window.onerror = function(errorMessage, scriptURI, lineNumber, columnNumber, error){
console.log(errorMessage);
console.log(scriptURI);
console.log(lineNumber);
console.log(columnNumber);
console.log(error);
}
</script>
<script type="text/javascript" src="./scripterror.js"></script>
</head>
<body>
</body>
</html>
```

在**scripterror.js**中抛出一个Error对象:

```js
throw new Error('Hello, Fundebug');
```

使用的[`http-server`](https://www.npmjs.com/package/http-server)挂载文件,打开[http://localhost:8080/index.html](http://localhost:8080/index.html),

在Chrome浏览器控制台下,可以看到详细的出错信息:

为了复现`Scrpt error.`, 将`scripterror.js`放到我在`coding.net`的个人项目下面:

```html
<!DOCTYPE html>
<html>
<head>
<title>Test Script error</title>
<script type="text/javascript">
window.onerror = function(errorMessage, scriptURI, lineNumber, columnNumber, error){
console.log(errorMessage);
console.log(scriptURI);
console.log(lineNumber);
console.log(columnNumber);
console.log(error);
}
</script>
<script type="text/javascript" src="http://coding.net/u/stefanzan/p/stefanzan/git/raw/coding-pages/public/js/src/scripterror.js"></script>
</head>
<body>
</body>
</html>
```
运行`http-server`, 结果如下:

因为违背同源策略,这时只能拿到`Script error.`。

### 总结

本文介绍了`Script error.`的由来,并提供了一个简单的实例来演示什么情况下出现`Script error.`。接下来,我们将对**Script error**进行[深度测试](http://fundebug.com/2017/04/06/test-script-error/)并提出[解决方法](http://fundebug.com/2017/04/07/solve-script-error/)

欢迎加入我们官方QQ群“全栈BUG监控交流”622902485

版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/04/05/understand-script-error/

Script error.全面解析的更多相关文章

  1. Fundebug前端JavaScript插件更新至1.7.1,拆分录屏代码,还原部分Script error.

    摘要: BUG监控插件压缩至18K. 1.7.1拆分了录屏代码,BUG监控插件压缩至18K,另外我们还原了部分Script error,帮助用户更方便地Debug.请大家及时更新哈~ 拆分录屏代码 从 ...

  2. Script error.深度测试

    Script error.全面解析中我们介绍了Script error.的由来.这篇博客,我们将各种情况(不同浏览器.本地远程托管JS文件)考虑进去,进行一个深度的测试,为读者带来一个全面的了解. G ...

  3. error LNK2019: 解析的外部符号 __imp__DispatchMessageW@4,在函数的符号 _WinMain@16 据引述

    错误: 1>WinMain.obj : error LNK2019: 解析的外部符号 __imp__DispatchMessageW@4,在函数的符号 _WinMain@16 据引述 1> ...

  4. 解决 "Script Error" 的另类思路

    本文由小芭乐发表 前端的同学如果用 window.onerror 事件做过监控,应该知道,跨域的脚本会给出 "Script Error." 提示,拿不到具体的错误信息和堆栈信息. ...

  5. Uncaught Error: Script error for "popper.js", needed by: bootstrap - require.js

    Uncaught Error: Script error for "popper.js", needed by: bootstrap https://requirejs.org/d ...

  6. script error总结

    移动端的页面在控制台报出一个script error,通常的原因有一下几点: 1. 脚本引入错误 可能是脚本的地址不对,协议不对(http或https问题),本地host文件绑定的地址不对 2. 方法 ...

  7. 怎样解决Script error报错问题

    如果脚本网址与网页网址不在同一个域(比如使用了 CDN), 那如果这个脚本执行报错了, 就会报:Script error. 由于同源策略, 浏览器禁止向外部脚本泄漏信息, 因此不会提供完整的报错信息, ...

  8. unity c# script error CS0664: Literal of type double cannot be implicitly converted to type `float'. Add suffix `f' to create a literal of this type

    例如在unity c# script中定义 private float x=0.0; 则会报 error CS0664: Literal of type double cannot be implic ...

  9. 模板函数(template function)出现编译链接错误(link error)之解析

    总的结论:    将template function 或者 template class的完整定义直接放在.h文件中,然后加到要使用这些template function的.cpp文件中. 1. 现 ...

随机推荐

  1. JAVA三大特性之三——多态

    作为JAVA的三大特性之一,多态性是很多人都没有弄清楚的一个重要特性,今天我就来从我所理解的角度来说一下. 首先,从他的字面意思来理解,多态,从其字面来理解就是多种形态,多种表现形式.根据这些,我最能 ...

  2. iOS 用Swipe手势和动画实现循环播放图片

    主要想法 添加3个ImageView展示图片,实现图片的无限循环. 使用Swipe手势识别用户向右或向左滑动图片. 使用CATransition给ImageView.layer添加动画,展示图片更换的 ...

  3. Window下JDK安装与配置

    今天项目组开会,由于.Net平台的限制无法满足现有业务需求,项目计划从.Net平台转Java平台,采用Java+Spark+Hadoop,之前关于Java和Hadoop的书也买的有只是平时看的少,最近 ...

  4. 好公司、行业、领导?应届生应根据什么选offer?

    两个年轻人大学毕业了,一个去了收入更高的大企业工作,一个去了收入较低的小作坊式工厂工作.你们说他们谁的青春时光最能升值呢?表面上看应该是大企业,可是大企业是做马车制造的,小作坊是做汽车的.现在人们都知 ...

  5. PetaPoco 快速上手

    今天来给大家分享一个好用的轻型的.net框架的ORM——PetaPoco 本着快速上手的原则,我们通过和EF对比,让大家能快速使用PetaPoco PetaPoco大家可能没有听说过,但大家一定听说过 ...

  6. Nginx+IIS+Redis 处理Session共享问题 2

    接下来主要说下利用nginx来测试 两台Windows server 1.10.120.131.210 -  端口84部署demo 2.10.120.131.211 -  端口84部署demo ngi ...

  7. CAEmitterLayer 粒子效果(发射器)

    //创建Layer CAEmitterLayer *emitterLayer = [CAEmitterLayer layer]; //边框 emitterLayer.borderWidth = 1.0 ...

  8. git 关键词扩展

    用习惯了svn 的 关键词扩展.自然在git上也会寻找. 不知道啥是svn的关键词扩展? 简单列举下: 对于subversion来说,一些版本信息是不需要手动添加的,subversion提供了关键字替 ...

  9. 一段从TXT导入excel的py脚本

    #创建文件file = Workbook(encoding='utf-8')#创建sleettableTotalTime = file.add_sheet('TotalTime')#每列给出名称tab ...

  10. 详解< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />

    < meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" /> 这是个是 ...