Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running JavaScript downloaded with XMLHttpRequest

I have a site that loads information using the XMLHttpRequest when a user clicks a link. The system works well but I would like to be able to execute JavaScript gathered in this process.

This is a problem as I would like to download the scripts 'on demand' if it were, rather than loading them all when the page is loaded.

Thanks for any help

like image 469
TomC Avatar asked Sep 16 '10 16:09

TomC


People also ask

How does XMLHttpRequest work in JavaScript?

XMLHttpRequest (XHR) objects are used to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing. XMLHttpRequest is used heavily in AJAX programming.

Should I use fetch or XMLHttpRequest?

Fetch is a new native JavaScript API, supported by most browsers today. Fetch allows you to make network requests similar to XMLHttpRequest . According to Google Developers Documentation Fetch makes it easier to make asynchronous requests and handle responses better than with the older XMLHttpRequest .

What is the purpose of XMLHttpRequest in AJAX?

XMLHTTPRequest is basically used in Ajax programming. It retrieve any type of data such as json, xml, text etc. It request for data in background and update the page without reloading page on client side. An object of XMLHTTPRequest is used for asynchronous communication between client and server.


4 Answers

I believe the recommended solution is something like this:

function include(scriptUrl)
{
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", scriptUrl);
    xmlhttp.onreadystatechange = function()
    {
        if ((xmlhttp.status == 200) && (xmlhttp.readyState == 4))
        {
            eval(xmlhttp.responseText);
        }
    };
    xmlhttp.send();
}

Or something like it.

However, be wary of this approach. It's vulnerable to cross-site scripting, which can open you (and your users) up to all sorts of nastiness. You'll want to take suitable precautions.

like image 65
Mike Hofer Avatar answered Oct 20 '22 23:10

Mike Hofer


Recently I found the answer (It works in Chrome, in another browsers it was not tested).

You can create dataURL string and put it into src attribute of script element.

var xhr = XMLHttpRequest(),
    doc = document;
xhr.open('GET', pathToJSFile, true);
xhr.onload = function () {

    var script = doc.createElement('script'),
        base64 = 'data:application/javascript;base64,';
    try {
        base64 += btoa(data.responseText);
    } catch (e) {
        // script file may contain characters that not included in Latin1
        var symbols = data.responseText.split('');
        for (var i = 0, l = symbols.length; i < l; i++) {
            var symbol = symbols[i];
            // here we are trying to find these symbols in catch branch
            try {
                btoa(symbol);
            } catch (e) {
                var code = symbol.charCodeAt(0).toString(16);
                while (code.length < 4) {
                    code = '0' + code;
                }
                // replace original symbol to unicode character
                symbols[i] = '\\u' + code;
            }
        }
        // create new base64 string from string with replaced characters
        base64 += btoa(symbols.join(''));
    } finally {
        script.src = base64;
        // run script
        doc.body.appendChild(script);
    }

};
xhr.send();

You can subscribe to xhr.onprogress to show progress bar.

Update. You can download your script file as blob, and then create blob-url.

var xhr = XMLHttpRequest(),
    doc = document;
xhr.responseType = 'blob';
xhr.open('GET', pathToJSFile, true);
xhr.onload = function () {

    var script = doc.createElement('script'),
        src = URL.createObjectURL(xhr.response);

    script.src = src;
    doc.body.appendChild(script);
};
xhr.send();
like image 29
Alex Skakun Avatar answered Oct 20 '22 22:10

Alex Skakun


You can run script downloaded in form of a string using

eval()

However I would recommend you to add new

<script src='..'></script>

to your document and have a callback which will be called when it will be downloaded. There are many utils and jquery plug-ins for that.

like image 6
Insomniac Avatar answered Oct 20 '22 22:10

Insomniac


I had the challenge on a mobile web-project, the magic was to set "overrideMimeType". This has been verified to work on Android 4.1 to Android 6.0.

var head = document.getElementsByTagName('head');
var injectedScript = document.createElement('script');
head[0].appendChild(injectedScript);

var myRequest = new XMLHttpRequest();
myRequest.onreadystatechange = function() {
  if (myRequest.readyState == 4 && myRequest.status == 200) {
        injectedScript.innerHTML = myRequest.responseText;
    //run a function in the script to load it   
  }
};

function start(){
    myRequest.open('GET', 'javascript-url-to-download', true);
    myRequest.overrideMimeType('application/javascript');
    myRequest.send();
}

start();
like image 1
janCoffee Avatar answered Oct 20 '22 23:10

janCoffee