为什么在从JavaScript生成HTML时使用\ x3C而不是<?

Mar*_*ker 29 html javascript browser escaping

我看到以下HTML代码用于从内容交付网络加载jQuery,但如果CDN不可用(例如在Modernizr文档中),则回退到本地副本:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js">\x3C/script>')</script>
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么语句中的最后一个<字符document.write()用转义序列替换\x3C<是一个安全的JavaScript字符,甚至在同一个字符串中使用,所以为什么要在那里逃避?是否只是为了防止错误的浏览器实现认为</script>字符串内部是真正的脚本结束标记?如果有的话,那里真的有任何浏览器会失败吗?

作为一个后续问题,我也看到了一个变体unescape()(在这个答案中给出)在野外也有几次.是否有一个原因,为什么这个版本似乎总是代替所有<>人物?

bal*_*pha 56

当浏览器看到时</script>,它认为这是脚本块的结尾(因为HTML解析器不知道JavaScript,它无法区分刚出现在字符串中的东西,以及实际上意味着结束脚本的东西元件).因此</script>,在HTML页面中出现的字面意思(在最好的情况下)将导致错误,并且(在最坏的情况下)是一个巨大的安全漏洞.

这就是为什么你不得不以某种方式阻止这个字符序列出现的原因.针对此问题其他常见的解决方法是"<"+"/script>""<\/script>"(他们都归结为同样的事情).

虽然有些人认为这是一个"错误",但它实际上必须以这种方式发生,因为根据规范,用户代理的HTML部分与脚本引擎完全分开.您可以将各种事物放入<script>标签中,而不仅仅是JavaScript.W3C提到了VBScript和TCL作为例子.另一个例子是jQuery模板插件,它也使用这些标签.

但即使在JavaScript中,您可以建议可以识别字符串中的此类内容,从而不将其视为结束标记,当您考虑注释时,会出现下一个歧义:

<script type="text/javascript">foo(42); // call the function </script>
Run Code Online (Sandbox Code Playgroud)

- 在这种情况下,浏览器应该怎么做?

最后,那些甚至不了解JavaScript的浏览器呢?他们会忽略部分之间<script></script>,但如果你给不同的语义字符序列</script>基础上的JavaScript的浏览器的知识,你会突然有两个不同的结果HTML解析阶段.

最后,关于替换所有尖括号的问题:我至少在99%的情况下说,这是为了混淆,即隐藏(从反病毒软件,审查代理(如在你的例子中)(嵌套的parens很棒) ))),你的JavaScript正在做一些HTML-y的事实.我不能想出隐藏任何东西的好技术理由,但</script>至少不能用于合理的现代浏览器(而且,我的意思是几乎比Mosaic更新的东西).

  • 大多数人,我想.我确信Chrome会将其解释为结束标记.(昨天查看) (2认同)