繁体   English   中英

Javascript外部脚本加载异常

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM