getScript本地加载而不是全局?

时间:2013-02-24 04:06:11

标签: javascript jquery ajax

据我所知,JQuery的getScript函数使用名为“global eval”的函数在全局上下文中加载脚本文件。是否有一个特定的设置或方法来改变它,所以它将在我调用它的函数中加载?

如果我执行以下代码名称,则返回undefined,因为它未在本地上下文中加载脚本。

    function callscript(){
        var name='fred';
    getScript(abc.js);
    }

//abc.js:
alert(name);

5 个答案:

答案 0 :(得分:5)

我相信我已经使用常规JQuery ajax调用找到了解决方案。诀窍是你将数据类型设置为'text',否则如果它的脚本或者使用getScript或替代.get()它将自动运行里面的脚本并将其放在全局上下文中。

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

按预期警告“ciao”:)

在任何人说任何事情之前我都在使用eval但在这种情况下完全没问题。

答案 1 :(得分:1)

正如您已经注意到的,文档中没有关于此的内容。我仔细检查了源代码,发现底层调用没有你传递的选项来覆盖这种行为。

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

据我所知,使用jQuery无法将脚本异步加载到本地作用域。 jQuery的API没有为您提供任何其他方法来配置它的用法。

我仍在研究如何使用其他技术。

答案 2 :(得分:0)

好的,我知道这是2017年,4年后,但似乎jQuery团队从不打扰解决这个问题,好吧。我有同样的问题,我认为这是解决方案,在本地上下文中使用getScript的实际预期方式。我注意到的是,代码无法在本地上下文中轻松地对代码进行评估,jQuery不知道它是怎么回事。我还没有深入,但是如果你看一下jQuery源代码,它是如何将脚本注入到文档中的,它是天才,它完全避免了eval。因此,它运行的脚本就好像它是通过脚本标记导入的文件一样。没有进一步的... ...

我决定反之亦然,它更好地解释了发生了什么。然后,您可以将其反转为相关示例。

如果您注意到getScript实际上在查询字符串中向服务器发送了唯一的ID。我不知道为什么他们没有在文档中提到这一点。用它来识别返回的脚本。但是你必须在后端做一些事情......

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包装了我们获取脚本的任何脚本.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 output
echo $output;

js通过getScript请求脚本的是什么,但是它并没有直接请求它使用php脚本来获取文件内容的文件。我这样做是为了我可以修改返回的数据并附加用于标识返回脚本的标头(这是一个大型应用程序,这里以这种方式请求了很多脚本)。

当getScript像往常一样在浏览器中运行返回的脚本时,脚本的实际内容不会运行,只是包装函数的声明具有唯一名称__script1237863498或类似的东西(数字由getScript在请求时提供)前面的那个脚本),附加到全局窗口对象。 然后js使用该响应来运行包装器函数并将属性注入到导入对象中......这对于请求任何范围的本地而言都是本地的。

答案 3 :(得分:-2)

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

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

答案 4 :(得分:-2)

我不知道jQuery实现,但name返回undefined的原因是因为namecallscript对象的私有属性。要否定这一点,您可以在函数调用之外声明变量:

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

//abc.js:
console.log(name) //Returns undefined
callscript(); //Call the script
console.log(name); //Returns "fred"