How To Fix Breaking JavaScript Issues Caused By Mobile Content (Ad) Blockers

When iOS 9 rolled out in September, it introduced mobile content (ad) blockers for Safari that were previously common on desktop browsers. A few have made their way ahead of the pack. While blocking unwanted ads, the content blockers also break common and non-malicious functionality. Here are the top two problems and how we fixed them at BuildZoom:

LocalStorage

localStorage is the modern way of storing data locally within the user’s browser. This is the common approach for checking the available of localStorage in the current browser:

if(typeof(Storage) !== "undefined") {
// Code for localStorage/sessionStorage.
} else {
// Sorry! No Web Storage support..
}

This approach produces a false-positive and leads to a JavaScript error being thrown:

QuotaExceededError: Dom exception 22: An attempt was made to add something to storage that exceeded the quota

The advanced method that properly tests for the availability of localStorage is:

try {
localStorage.setItem('test', '1');
localStorage.removeItem('test');
// Code for localStorage/sessionStorage.
} catch (error) {
Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype.setItem = function() {};
// Sorry! No Web Storage support..
}

With this approach, there is an attempt to use localStorage, wrapped in a try/catch, to properly handle the erroneous case.

Google Maps JavaScript API

The Google Maps JavaScript API powers much of the web. It offers a variety of mapping, geocoding, and typeahead services. Content blockers block the loading of the main JavaScript file from the Google CDN. When the library is loaded via a script tag

https://maps.googleapis.com/maps/api/js?v=3.20 //additional query string parameters have been removed for the purpose of this post

a warning is displayed in the browser’s console:

Content blocker prevented frame displayed (your domain) from loading a resource from https://maps.googleapis.com/maps/api/js?v=3.20

Then an error is thrown:

Error: Can't find variable: google

The solution is to create a local JavaScript file on your server and paste the code from https://maps.googleapis.com/maps/api/js?v=3.20 into it. Include the local file via script tag right after the inclusion of the JS API itself. Wrap the pasted code with:

if (typeof google === 'undefined') {
// paste code from https://maps.googleapis.com/maps/api/js?v=3.20 here
}

Surprisingly the additional Google JS files that are injected into the DOM are not blocked.