Javascript AJAX include file witth eval

13,327

Solution 1

jQuery always has something for everything:

http://api.jquery.com/jQuery.getScript/

Loads a javascript file from url and executes it in the global context.

edit: Oops, didn't see that you weren't using jQuery. Everyone is always using jQuery...

Just do:

var scrpt = document.createElement('script');
scrpt.src='http://www.example.com/data.js';
document.head.appendChild(scrpt);

Solution 2

i think you should take a look at this site

this site talks about dynamic loading and callbacks (with examples) - where you can call a function in the loaded script after it loads. no jQUery, just pure JS.

Solution 3

This depends on a lot of factors, but in most cases, you will want to load all of your code/html/css in one sitting. It takes fewer requests, and thus boast a higher perceived performance benefit. Unless your code file is over several Megabytes big, loading it when a user requests it is unnecessary.

In addition to all of this, modifying innerHTML and running scripts via eval can be very cumbersome and risky (respectively). Many online references will back this point. Don't assume that, just because a library is doing something like this, it is safe to perform.

That said, it is entirely possible to load external js files and execute them. One way is to stick all of the code into a newly created script tag. You can also just try running the code in an eval function call (though it isn't recommended).

address = "testscript.js";

var req = (window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
if(req == null) {
    console.log("Error: XMLHttpRequest failed to initiate.");
}
req.onload = function() {
    try {
        eval(req.responseText);
    } catch(e) {
        console.log("There was an error in the script file.");
    }
}
try {

    req.open("GET", address, true);
    req.send(null);

} catch(e) {
    console.log("Error retrieving data httpReq. Some browsers only accept cross-domain request with HTTP.");
}
Share:
13,327
Tom
Author by

Tom

Updated on June 04, 2022

Comments

  • Tom
    Tom almost 2 years

    Suppose I have

    1) a HTML document.

    2) This HTML document loads Javascript file "code.js" like this:

    <script src="code.js">
    

    3) User clicks button which runs "fetchdata" function in "code.js",

    4) "fetchdata" function looks like this:

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState==4) {
            myjsdata = xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET", 'http://www.example.com/data.js', false);
    xmlhttp.send(null);
    

    ...

    Now how do I do the following successfully:

    I want to insert/eval my Javascript in a way, so all functions in "code.js" including "fetchdata" and functions defined above/below can access the data (structures, declarations, pre-calculated data values etc.) in "data.js".

    (If this was possible, it would be idea since I could wait loading the actual JS data file until the user explicitly requests it.)

  • Tom
    Tom over 12 years
    Thanks! So instead of using Ajax/related, I can use your code in "code.js" ... And functions inside "code.js" will have immediate access to all variables etc. defined inside "data.js"? I will try it out now :)
  • mowwwalker
    mowwwalker over 12 years
    @Tom, Yes, adding a script element to the head executes it.
  • Michael Lorton
    Michael Lorton over 12 years
    "Step 1: If you are using jQuery, call the getScript function. Step 2: If you are not using jQuery, start using jQuery and return to Step 1."
  • Tom
    Tom over 12 years
    This seems to work in IE9, but it does not seem to work in FireFox. After applying your "appendChild" code, "fetchdata" immediately tries to call a function (that initializes data) in the just appended "data.js" file... But FireFox says this call is defined.
  • Tom
    Tom over 12 years
    @Malvolio It is important for me to keep footprint as small as possible.
  • Tom
    Tom over 12 years
    The thing is my data.js is between 200-500kb. I prefer to only load it when needed. However, where does "eval" put the code into scope / declaration order? Do I just need to call "eval" and all functions/vairables etc. will be immediately available?
  • Tom
    Tom over 12 years
    I meant FF says the call "is not defined". I have also tried to use "dochead.insertBefore(my_script_data, dochead.firstChild);", no luck :(
  • Joseph
    Joseph over 12 years
    if i had to choose between using a buggy multi-liner script (which may not be scalable and robust) and using a proven library with a one-liner call, i'd go for the library approach - they were made so that you don't have to reinvent the wheel.
  • Tom
    Tom over 12 years
    And in theory there is no upper limit on data file size... Could easily be much lager if people were okay with it... However, for now I operate with a "minimize size and time" mentality :)
  • Jeffrey Sweeney
    Jeffrey Sweeney over 12 years
    eval executes in the global scope I believe. It really is that simple to run a foreign script, which is why it is so dangerous.
  • Tom
    Tom over 12 years
    Argh, I had forgot this. Oh well, I will work out something :) I would prefer your solution over the Ajax one since yours will also work when running offline. (I don't know if my code will run on CDs, websites or whereever, so it is a big advantage with your solution.)
  • Tom
    Tom over 12 years
    Using both methods listed in "Detecting Load Completion" (+ making sure I do not risk getting called with both) actually solved the rest of my problems in newest versions of IE,FF,Opera,Chrome ... Thanks :)
  • Tom
    Tom over 12 years
    Combining Walkerneo with solutions listed in Joseph link below has solved my problems. Thanks everyone! :)
  • Michael Lorton
    Michael Lorton over 12 years
    @Tom -- I was mostly kidding, but I have to agree with what Joseph said. The stuff in a framework is often very difficult to get right. Good frameworks often have ways to strip them down to just what you need.
  • Tom
    Tom over 12 years
    Just wanted to say thanks for this suggestion as well! I upvoted all responses since they have all been valuable :)
  • Tom
    Tom over 12 years
    @Malvolio -- In this specific case space is of high importance to me. (Even if it may turn out I am overly worrying about this.) In addition, I also need to distribute my code together with my executable, and I prefer to limit 3rd party stuff for this reason as well. (Basicly I have a program that pre-calculates keyword/phrase scores, importance of pages, other content metrics etc. and then throws it all into size-optimized Javascript data files giving reasonable quality site-wide online/offline search.)
  • Michael Lorton
    Michael Lorton over 12 years
    Ah,here's what you want to do: don't write your library without a framework, write it with several frameworks. Withough too much difficulty, you can make a version the works with jQuery, another works with YUI, and so on. Your customers are likely to be using one anyway, and if one isn't, it is perfectly reasonable to require them to start.
  • Tom
    Tom over 12 years
    In my dealing with customers, things just have to work out-of-the-box if you want to get the most sales. Anyhow, in this case, I don't really see the need for framework. The proposed solutions suggested here worked out great, only took a few lines of code, and I learned something at the same time :) But yes, I know JQuery is popular and where I ever to make a larger Javascript application, frameworks like JQuery would be a natural fit, I agree! :)
  • Tim
    Tim almost 10 years
    I am new to JS and I have been searching for this for a couple of days!!! You are a LIFE saver!
  • trusktr
    trusktr almost 10 years
    But the script I'm trying to get is jQuery. What now?
  • trusktr
    trusktr almost 10 years
    This worked perfect. I was trying to load jQuery... so I didn't have jQuery to begin with to load jQuery.
  • IgniteCoders
    IgniteCoders almost 10 years
    Works perfectly. i let here my implementation.