![](/img/trans.png)
[英]Loading external javascript in a bookmarklet via a script loader
[英]Javascript external script loading strangeness
我正在维护一个遗留JavaScript应用程序,该应用程序的组件分为4个JS文件。
它们是“ Default.aspx”,“ set1.aspx”,“ set2.aspx”和“ set3.aspx”。 ASPX页面从属于它们各自集合的多个(所有)源文件中写出压缩的JS,并将content-type标头设置为“ text / javascript”。
通过添加对第一个集合的引用并创建主条目对象来调用该应用程序。
<script src="/app/default.aspx" type="text/javascript"></script>
<script type="text/javascript>
var ax;
// <body onload="OnLoad()">
function OnLoad() {
ax = new MyApp(document.getElementById("axTargetDiv"));
}
</script>
在第一组脚本(default.aspx)的末尾是以下确切代码:
function Script(src) {
document.write('<script src="' + src + '" type="text/javascript"></script>');
}
Script("set1.aspx?v=" + Settings.Version);
它将加载第二组脚本(set1.aspx)。 在所有主要浏览器(IE6-8 Firefox Safari Opera Chrome)中,此操作均无任何错误。
但是,由于我一直在安静地使用此脚本,因此我想在很多地方简化函数调用,并错误地内联了上述Script函数,从而产生了以下代码:
document.write('<script src="set1.aspx?v=' + Settings.Version + '" type="text/javascript"></script>');
现在,当使用测试页进行测试时,它现在在所有浏览器中都会引发以下错误:
MyApp is not defined.
这发生在以下行: ax = new MyApp(...
因为Visual Studio JS调试器和 Firebug报告了它。
在此问题的前4个答案中,我尝试了各种方法,但均无济于事。 使MyApp成功加载的唯一方法是仅将实际的“添加脚本”代码放入函数内(即document.write('script')
行):
如果我将document.write
行放在一个函数内,它将起作用,否则,它将不会起作用。 发生了什么?
分割和/或转义脚本文本不起作用。
要查看该问题,请查看其脚本元素中的第一行:
<script type="text/javascript">
document.write('<script src="set1.aspx?v=1234" type="text/javascript"></script>');
</script>
因此,出现了HTML解析器,并看到了开始的<script>标记。 在<script>中,常规的<tag>解析被禁用(以SGML术语,该元素具有CDATA内容)。 为了找到脚本块的结尾,HTML解析器会寻找匹配的关闭标记</ script>。
它找到的第一个是字符串文字中的一个。 HTML解析器无法知道它在字符串文字中,因为HTML解析器对JavaScript语法一无所知,因此他们仅对CDATA有所了解。 因此,您实际上要说的是:
<script type="text/javascript">
document.write('<script src="set1.aspx?v=1234" type="text/javascript">
</script>
即,未封闭的字符串文字和未完成的函数调用。 这些会导致JavaScript错误,并且永远不会编写所需的脚本标记。
解决该问题的常见尝试是:
document.write('...</scr' + 'ipt>');
从技术上讲,这仍然是错误的(并且不会验证)。 这是因为在SGML中,结束CDATA元素的字符序列实际上不是'</ tagname>',而只是'</'-仍然在上面的行中存在。 浏览器通常更宽容,实际上它会允许它。
最好的解决方案可能是转义序列。 有几种可能,但最简单的方法是使用JavaScript字符串文字转义('\\ xNN'):
document.write('\x3Cscript src="set1.aspx?v=1234\x26w=5678" type="text/javascript"\x3E\x3C/script\x3E');
上面的代码转义了所有'<','>'和'&'字符,这不仅停止了字符串中的'</'序列出现,而且允许将其插入XHTML脚本块中而不会引起错误。
(在XHTML中,没有CDATA元素,因此这些字符的含义与普通内容中包含的含义相同,并且脚本块中的字符串'<script>'实际上会创建嵌套的脚本元素!这是可能的。可以使用<![CDATA [部分)在XHTML脚本块中允许<>&,但这有点难看,通常最好避免在内联脚本中使用这些字符。)
1)确保在页面“实际”包含脚本之前,不要尝试引用MyApp。
2)尝试像这样在嵌入式加载程序中破坏单词“ script”:
<script type="text/javascript">
document.write('<scr' + 'ipt src="set1.aspx?v=1234" type="text/javascript"></scr' + 'ipt>');
</script>
另外,也可以使用我从Google Analytics(分析)代码中借用的,可以成功使用的以下语法:
<script type="text/javascript">
document.write(unescape("%3Cscript src='set1.aspx?v=1234' type='text/javascript'%3E%3C/script%3E"));
</script>
您也可以尝试:
var script = document.createElement("script");
script.src = "set1.aspx?v=1234";
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
史蒂夫
如果可以使用JQuery,则可以使用以下内容:
$.getScript("set1.aspx?v=1234");
这会将脚本加载到全局javascript上下文中。 确保将响应的内容类型设置为“ text / javascript”。
希望这可以帮助...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.