Skip to content Skip to sidebar Skip to footer

Getscript Local Load Instead Of Global?

From what I have read JQuery's getScript function loads the script file in a global context using a function called 'global eval'. Is there a particular setting or method to change

Solution 1:

I believe I have found the solution using a regular JQuery ajax call. The trick is you set the datatype to 'text' as otherwise if its script or if use getScript or the alternative .get() it will auto run the script inside and place it in the global context.

functionabc(){
    var msg="ciao";
    $.ajax({
      url: 'themes/_default/system/message.js',
      success: function(data){
          eval(data);
      },
      dataType: "text"
    });
    }
    //message.js
(function() {
    alert(msg);
})();

This alerts 'ciao' as expected :)

Before anyone says anything yes I'm using eval but its perfectly fine in this situation.

Solution 2:

As you already noticed, there's nothing in the docs regarding this. I double checked the source code and found that the underlying call has no options for you to pass to override this behavior.

// http://code.jquery.com/jquery-1.9.1.js
...
getScript: function( url, callback ) {
    return jQuery.get( url, undefined, callback, "script" );
},
...

As far as I can tell, loading a script asynchronously into a local scope is not possible with jQuery. jQuery's API doesn't give you any other means to configure its usage like this.

I am still investigating how it might be possible using some other technique.

Solution 3:

Ok i know this is 2017, 4 years later, but it seems jQuery team never bothered to address this issue, well sort of. I had the same problem and i think this is the solution, the actual intended way of using getScript in a local context. What I noticed was that there is no way that code could be easily eval'd in a local context against your code, which jQuery has no idea how it is going. I haven't gone deeper, but if you look at the jQuery source, how it is injecting the script into the document, it's genius, it avoids eval altogether. The script it therefore ran as if it's a file that was imported through script tag. Without further ado...

I have decided to do the vice-versa of the situation, it better explains what's going on. You can then reverse it to that example in question.

If you noticed getScript actually sends a unique ID to the server in the query string. I don't know why they didn't mention this in documentation. Use that to identify returned scripts. But you have to do something in the backend...

let imports;

$.getScript("scripts.php?file=abc.js", (data, textStatus, jqXHR) => {
    window[jqXHR.getResponseHeader('X-scriptID')](imports);
    alert (imports.name);
});

abc.js:

imports.name = 'fred';

backend wraps whatever script we are getting scripts.php:

// code that gets the file from  file system into var $output$output = file_get_contents($_REQUEST['file']);

// generate a unique script function name, sort of a namespace$scriptID = "__script" . $_REQUEST['_'];

// wrap the script in a function a pass the imports variable // (remember it was defined in js before this request) we will attach// things we want to become local on to this object in script file$output = "window.".$scriptID."=function(imports) { ".$output." };";

// set the script id so we can find this script in js           
header ("X-scriptID: " . $scriptID);

// return the outputecho$output;

What going is that the js requests a script through getScript, but it doesn't request directly to the file it uses a php script to fetch the contents of the file. I am doing this so that i can modify the returned data and attach headers that are used to id the returned script (this is large app in mind here where a lot of scripts are requested this way).

When getScript runs the returned script in the browser as usual, the actual content of the script are not ran, just a declaration of the wrapper function with a unique name __script1237863498 or something like (the number was given by getScript upon requisition of that script earlier), attached to the global window object. Then js uses that response to run the wrapper function and inject properties into the imports object... which become local to the requesting whatever's scope.

Solution 4:

I don't know jQuery implementation, but the reason name is returning undefined is because name is a private property of the callscript object. To negate this, you could declare the variable outside of the function call:

var name = ''; //Declare name outside of the functionfunctioncallscript(){
  name='fred';
  getScript('abc.js'); //Shouldn't it be $.getScript? and argument should be passed as a string
}

//abc.js:console.log(name) //Returns undefinedcallscript(); //Call the scriptconsole.log(name); //Returns "fred"

Solution 5:

// global.jsvar global1 = "I'm a global!";

// other js-filefunction testGlobal () {
    alert(global1);
}

Post a Comment for "Getscript Local Load Instead Of Global?"