根据我的阅读,JQuery 的 getScript 函数使用名为“global eval”的函数在全局上下文中加载脚本文件。是否有特定的设置或方法来改变它,所以它会在我调用它的函数中加载?
如果我执行以下代码名称,则返回未定义,因为它没有在本地上下文中加载脚本。
function callscript(){
var name='fred';
getScript(abc.js);
}
//abc.js:
alert(name);
根据我的阅读,JQuery 的 getScript 函数使用名为“global eval”的函数在全局上下文中加载脚本文件。是否有特定的设置或方法来改变它,所以它会在我调用它的函数中加载?
如果我执行以下代码名称,则返回未定义,因为它没有在本地上下文中加载脚本。
function callscript(){
var name='fred';
getScript(abc.js);
}
//abc.js:
alert(name);
我相信我已经找到了使用常规 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 但在这种情况下它非常好。
正如您已经注意到的那样,文档中没有关于此的任何内容。我仔细检查了源代码,发现底层调用没有选项可供您传递以覆盖此行为。
// http://code.jquery.com/jquery-1.9.1.js
...
getScript: function( url, callback ) {
return jQuery.get( url, undefined, callback, "script" );
},
...
据我所知,使用 jQuery 将脚本异步加载到本地范围是不可能的。jQuery 的 API 没有为您提供任何其他方式来配置它的用法。
我仍在研究如何使用其他技术。
好吧,我知道这是 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 使用该响应来运行包装函数并将属性注入到导入对象中......这成为请求范围内的本地对象。
// global.js
var global1 = "I'm a global!";
// other js-file
function testGlobal () {
alert(global1);
}
我不知道 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"