← Asynchronous JavaScript Include Download

/*-----------------------------------------------------------------------------\ | Asynchronously includes JavaScript. Can fall back to a second link. | +------------------------------------------------------------------------------+ | Usage: | | <script> | | cssAsync("https://cdn.example.com/js/script.js", "/js/script.js"); | | <script> | +---------+-----------+----------+---------------------------------------------| | @param | string | primary | Primary URL (typically a CDN). | | @param | string | fallback | Fallback URL (typically a local copy). | | @param | string | callback | Callback function after <script> loads. | | @return | void | | | \---------+-----------+----------+--------------------------------------------*/ function jsAsync(primary, fallback, callback){ /* Build AJAX request. */ var xhr = new XMLHttpRequest(); xhr.open("HEAD", primary); /* AJAX state change callback. */ xhr.onreadystatechange = function(){ /* AJAX completion. */ if(this.readyState === this.DONE){ /* Create <script> to hold script. */ var script = document.createElement("script"); /* Use CDN on success. || Cloudflare returns 503 on HEADs. */ if(this.status === 200 || this.status === 503){ script.src = primary; }else{ script.src = fallback; } /* Add nonce if applicable. */ var nonce = ""; var nonces = document.querySelectorAll("[nonce]"); for(var i = nonces.length - 1; i >= 0; i--){ nonce = nonces[i].getAttribute("nonce"); if(nonce){ script.setAttribute("nonce", nonce); break; } } /* Apply callback. */ script.onload = callback; /* Insert into <head>. */ document.head.insertBefore(script, document.head.firstChild); } }; /* Send AJAX request. */ try{xhr.send()}finally{} }