Skip to content

Instantly share code, notes, and snippets.

@rankun203
Last active January 2, 2017 15:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rankun203/1b0069a7005b22552fd3e24a2493e881 to your computer and use it in GitHub Desktop.
Save rankun203/1b0069a7005b22552fd3e24a2493e881 to your computer and use it in GitHub Desktop.
Use service worker to quickly fail non accessible URLs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Service Worker test</title>
<script>
navigator.serviceWorker.getRegistration().then(function (registration) {
if (!registration || !navigator.serviceWorker.controller) {
navigator.serviceWorker.register('./sw.js').then(function () {
console.log('Service worker registered, reloading the page');
window.location.reload();
});
} else {
console.log('DEBUG: client is under the control of service worker');
}
});
</script>
<link rel='stylesheet' id='extra-fonts-css'
href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&#038;subset=latin,latin-ext'
type='text/css' media='all'/>
</head>
<body>
<script src="https://lodestreams-com.disqus.com/count.js?check-china=true"></script>
</body>
</html>
/** Indicates that current user is browsing from China. */
ServiceWorkerGlobalScope.inChina = null;
var DEBUG = true;
var EMPTY_RESPONSE = '';
/** The patterns to be checked against the requesting URL. */
var CHECK_CHINA_PATTERNS = [
'check-china=true',
'disqus.com',
'googleapis.com'
];
/**
* Clear inChina global var.
* User may request through a proxy sometime, so it's better to just
* clear the inChina var in nearly future.
*
* @param sec {Number} Seconds later to take the action. Default is 2 minutes.
*/
function clearInChinaVarLater(sec) {
clearTimeout(ServiceWorkerGlobalScope.clearInChinaVarLater_TIMER);
ServiceWorkerGlobalScope.clearInChinaVarLater_TIMER = setTimeout(function () {
console.log('ServiceWorkerGlobalScope.inChina = undefined');
ServiceWorkerGlobalScope.inChina = undefined;
}, sec || 2 * 60 * 1000);
}
/**
* Fetch resource with China detection.
* If in China, returns Empty response, otherwise returns a real request response.
* This function will also cache the inChina as a service worker level global variable, and will clear it later.
* @param theRequest {Request} The requesting Request, needed for firing another real request (event.request).
* @returns {Response|Promise} response if it's a empty response, Promise if it's requesting the real URL.
*/
function fetchWithChinaDetection(theRequest) {
clearInChinaVarLater();
if (ServiceWorkerGlobalScope.inChina === false) {
return fetch(theRequest);
}
if (ServiceWorkerGlobalScope.inChina === true) {
return new Response(EMPTY_RESPONSE);
}
return fetch('https://freegeoip.net/json/')
.then(function (resp) {
return resp.json()
})
.then(function (json) {
var country = json && json.country_code;
if (country && country.indexOf('CN') >= 0) {
if (DEBUG) console.log('ServiceWorkerGlobalScope.inChina === true');
ServiceWorkerGlobalScope.inChina = true;
return new Response(EMPTY_RESPONSE);
}
if (DEBUG) console.log('ServiceWorkerGlobalScope.inChina === false');
ServiceWorkerGlobalScope.inChina = false;
return fetch(theRequest);
});
}
/**
* Entrance event.
* If current request is considered not accessible in China,
* check current user location before make the decision.
*
* Otherwise, for normal requests, just return their originals.
* @param event {Event} The request Event, event.request is a Request.
*/
self.onfetch = function (event) {
var checkChina = false;
CHECK_CHINA_PATTERNS.forEach(function (p) {
checkChina = checkChina || event.request.url.indexOf(p) >= 0;
});
if (checkChina) {
if (DEBUG) console.log('checkChina is true for ' + event.request.url);
return event.respondWith(fetchWithChinaDetection(event.request));
}
return event.respondWith(fetch(event.request));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment