Script Error – Here’s why it happens and how to fix it

Raygun helps software development teams detect and diagnose software errors with greater speed and accuracy. If you’re working on a website and have Raygun hooked into its client-side JavaScript, one of the first things you probably noticed was the rather unhelpful “Script Error” appearing in your dashboard.

You may have also seen this appear in the browser console while developing. Script Errors happen when errors from scripts loaded from a different domain than the origin are caught by the global window.onerror handler.

Browsers may behave in this way as a security feature to protect against potentially malicious scripts injected or hosted by other sites. Usually from reading user data such as cookies (quite rightly, I’m sure you’ll agree).

This is termed the Same-Origin Policy, and means that scripts only have full access rights if they are loaded from the same origin domain as the original document. When the script passes the CORS validation.

Script Error – The Same-Origin Policy

CORS and the Same-Origin Policy do however present a problem with regards to the architecture of modern web sites and applications.

Due to the nature of HTTP 1.1, frequently key resources including JavaScripts are hosted on non-origin (also called ‘third-party’) domains. In particular CDNs, as using the massive resources of public clouds keeps both costs and response times low.

When your web application code is defined and loaded in a script hosted on a different domain to the one in the address bar, errors that hit window.onerror won’t have any stack trace or message context for you to debug.

This is not a problem when developing locally, but becomes a critical issue when trying to figure out why a site is breaking on a user’s machine. This is most obvious when Raygun4JS reports these errors, and the error groups lack any indication as to what happened.

Controlling the Same-Origin Policy

The spec and implementation for controlling the Same-Origin Policy is documented nicely here. The Browser Compatibility matrix is a valuable read. You’ll notice proper implementations are only available in recent versions of the evergreen browsers. Which come with caveats in the bug tickets, or are plain not supported.

There are two key pieces of metadata to include to allow a cross-domain script to report errors correctly in a modern browser. As the documentation lists above, the first is the presence of the ‘crossorigin’ attribute on the appropriate script tag. By example:

<script crossorigin="anonymous" src="http://anotherdomain/foo.js"></script>

The second critical bit of data is the presence of an HTTP header on the response from the third-party domain containing the JavaScript. This is:

Access-Control-Allow-Origin: *

The wildcard in this example allows all sites to report errors with full data. This is appropriate for a CDN where the script may be requested by any third-party domain. If this is a private host for a known set of domains, you can provide that list in place of the wildcard.

Different browser behaviours regarding script error

Depending on what browser your users are running, the above properties may or may not have an effect. This sums up the situation as of writing:

  • Chrome 30+
  • Firefox 13+
  • Opera 12.50+
  • Safari (at least 6+)

In these browsers, if the script attribute is present, the HTTP header will need to be also present. Otherwise the script will be blocked.

Firefox has additional behavior for RuntimeErrors. These will be provided to window.onerror regardless of the two properties. Apparently these aren’t considered a security risk. Syntax errors, however, will be blocked in both Gecko and WebKit browsers, if crossorigin is present but the associated cross-origin domain lacks the header.

  • Internet Explorer <= 10

Errors will be reported with all available data in IE 10 and below. Now considered a security issue.

  • Internet Explorer 11+

Third-party errors will not contain any data, and the attributes are not respected at time of writing. We’re hoping that Microsoft Edge will resolve this.

Ready to blast away script errors?

Like many elements of software development, there are pitfalls to be aware of when it comes to security and legacy platform support. CORS support and third-party errors are just one of these. Hopefully with this guide you should be able to ensure you are receiving the error data you need to fix bugs and stop seeing script error on your cross-origin scripts. All while guarding against malicious third-party scripts and script injection.

Got questions about this post? Let us know in the comments section below. If you haven’t tried out Raygun Crash Reporting, see what the buzz is about by starting your free 14-day trial here.