cha*_*rit 0 javascript external-script
我正在维护一个遗留的javascript应用程序,它的组件分为4个JS文件.
它们是"Default.aspx","set1.aspx","set2.aspx"和"set3.aspx".ASPX页面从属于其各自集合的多个(所有不同的)源文件中写出压缩的JS,并将内容类型标题设置为"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>
Run Code Online (Sandbox Code Playgroud)
在第一组脚本(default.aspx)的末尾是以下完全代码:
function Script(src) {
document.write('<script src="' + src + '" type="text/javascript"></script>');
}
Script("set1.aspx?v=" + Settings.Version);
Run Code Online (Sandbox Code Playgroud)
它加载第二组脚本(set1.aspx).这在所有主流浏览器(IE6-8 Firefox Safari Opera Chrome)中都没有任何错误.
但是,由于我一直在使用这个脚本安静,我想在很多地方简化函数调用并错误地内联上面的Script函数,从而得到以下代码:
document.write('<script src="set1.aspx?v=' + Settings.Version + '" type="text/javascript"></script>');
Run Code Online (Sandbox Code Playgroud)
在使用测试页面进行测试时,现在会在所有浏览器中抛出以下错误:
MyApp is not defined.
Run Code Online (Sandbox Code Playgroud)
这发生在这一行:ax = new MyApp(...Visual Studio JS调试器和 Firebug报告它.
我已经尝试了在这个问题的前4个答案中的各种方法无济于事.只有将实际的"添加脚本"代码放在一个函数(即document.write('script')行)中,才能使MyApp成功加载:
如果我将该document.write行放在一个函数中,它就可以工作,否则就不行.发生了什么?
拆分和/或转义脚本文本不起作用.
要查看问题,请查看其script元素中的顶行:
<script type="text/javascript">
document.write('<script src="set1.aspx?v=1234" type="text/javascript"></script>');
</script>
Run Code Online (Sandbox Code Playgroud)
因此,HTML解析器出现并看到了开始的<script>标记.在<script>内部,正常的<tag>解析被禁用(在SGML术语中,元素具有CDATA内容).要查找脚本块的结束位置,HTML解析器将查找匹配的close-tag </ script>.
它找到的第一个是字符串文字中的一个.HTML解析器无法知道它在字符串文字中,因为HTML解析器对JavaScript语法一无所知,他们只知道CDATA.所以你实际上说的是:
<script type="text/javascript">
document.write('<script src="set1.aspx?v=1234" type="text/javascript">
</script>
Run Code Online (Sandbox Code Playgroud)
也就是说,一个未闭合的字符串文字和一个未完成的函数调用.这些会导致JavaScript错误,并且永远不会编写所需的脚本标记.
解决问题的常见尝试是:
document.write('...</scr' + 'ipt>');
Run Code Online (Sandbox Code Playgroud)
这在技术上仍然是错误的(并且不会验证).这是因为在SGML中,结束CDATA元素的字符序列实际上不是'</ tagname>'而只是'</' - 一个仍然存在于上面一行中的序列.浏览器通常更宽容,并且在实践中允许它.
可能最好的解决方案是逃避序列.有一些可能性,但最简单的是使用JavaScript字符串文字转义符('\ xNN'):
document.write('\x3Cscript src="set1.aspx?v=1234\x26w=5678" type="text/javascript"\x3E\x3C/script\x3E');
Run Code Online (Sandbox Code Playgroud)
上面的所有'<','>'和'&'字符都会转义,它不仅会停止出现在字符串中的'</'序列,还会允许它插入到XHTML脚本块中而不会导致错误.
(在XHTML中,没有CDATA元素这样的东西,所以这些字符与正常内容中包含的含义相同,脚本块中的字符串'<script>'实际上会创建一个嵌套的脚本元素!这是可能的通过使用<![CDATA [部分]允许<>&在XHTML脚本块中,但它有点难看,通常最好避免在内联脚本中使用这些字符.)
| 归档时间: |
|
| 查看次数: |
841 次 |
| 最近记录: |