4

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

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

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

//abc.js:
alert(name);
4

5 回答 5

6

我相信我已经找到了使用常规 JQuery ajax 调用的解决方案。诀窍是您将数据类型设置为“文本”,否则如果其脚本或使用 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 但在这种情况下它非常好。

于 2013-02-24T05:29:31.637 回答
1

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

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

据我所知,使用 jQuery 将脚本异步加载到本地范围是不可能的。jQuery 的 API 没有为您提供任何其他方式来配置它的用法。

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

于 2013-02-24T04:26:10.370 回答
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';

后端包装我们得到的任何脚本 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 output
echo $output;

发生的事情是 js 通过 getScript 请求脚本,但它不直接请求文件,它使用 php 脚本来获取文件的内容。我这样做是为了修改返回的数据并附加用于标识返回脚本的标头(这是一个大型应用程序,这里需要大量脚本)。

当 getScript 像往常一样在浏览器中运行返回的脚本时,脚本的实际内容不会运行,只是使用唯一名称 __script1237863498 或类似名称的包装函数声明(该编号由 getScript 在之前请求该脚本时给出),附加到全局窗口对象。然后 js 使用该响应来运行包装函数并将属性注入到导入对象中......这成为请求范围内的本地对象。

于 2017-06-06T12:50:40.437 回答
-2
// global.js
var global1 = "I'm a global!";

// other js-file
function testGlobal () {
    alert(global1);
}
于 2013-02-24T04:11:49.657 回答
-2

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

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"
于 2013-02-24T04:21:22.310 回答