简体   繁体   English

"为什么要拆分<script> tag when writing it with document.write()?"

[英]Why split the <script> tag when writing it with document.write()?

Why do some sites (or advertisers that give clients javascript code) employ a technique of splitting the <script> and/or </script> tags up within document.write() calls?为什么某些网站(或为客户提供 JavaScript 代码的广告商)采用一种技术,将<script>和/或</script>标记拆分到document.write()调用中?

I noticed that Amazon does this as well, for example:我注意到亚马逊也这样做,例如:

<script type='text/javascript'>
  if (typeof window['jQuery'] == 'undefined') document.write('<scr'+'ipt type="text/javascript" src="http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js"></sc'+'ript>');
</script>

<\/script><\/code> has to be broken up because otherwise it would end the enclosing <script><\/script><\/code> block too early. <\/script><\/code>必须被分解,否则它会过早结束封闭的<script><\/script><\/code>块。 Really it should be split between the <<\/code> and the \/<\/code> , because a script block is supposed (according to SGML) to be terminated by any end-tag open (ETAGO) sequence (ie <\/<\/code> )<\/a> :实际上它应该在<<\/code>和\/<\/code>之间分开,因为脚本块应该(根据 SGML)被任何结束标签打开(ETGO)序列(即<\/<\/code> )终止<\/a>:

Although the STYLE and SCRIPT elements use CDATA for their data model, for these elements, CDATA must be handled differently by user agents.尽管 STYLE 和 SCRIPT 元素使用 CDATA 作为其数据模型,但对于这些元素,用户代理必须以不同方式处理 CDATA。 Markup and entities must be treated as raw text and passed to the application as is.标记和实体必须被视为原始文本并按原样传递给应用程序。 The first occurrence of the character sequence " <\/<\/code> " (end-tag open delimiter) is treated as terminating the end of the element's content.字符序列“ <\/<\/code> ”(结束标记打开分隔符)的第一次出现被视为终止元素内容的结尾。 In valid documents, this would be the end tag for the element.在有效文档中,这将是元素的结束标记。

<\/blockquote>

However in practice browsers only end parsing a CDATA script block on an actual <\/script><\/code> close-tag.然而,实际上浏览器只在实际的<\/script><\/code>关闭标记上结束解析 CDATA 脚本块。

In XHTML there is no such special handling for script blocks, so any <<\/code> (or &<\/code> ) character inside them must be &escaped;<\/code>在 XHTML 中,脚本块没有这种特殊处理,因此其中的任何<<\/code> (或&<\/code> )字符都必须&escaped;<\/code> like in any other element.就像在任何其他元素中一样。 However then browsers that are parsing XHTML as old-school HTML will get confused.但是,将 XHTML 解析为老式 HTML 的浏览器会感到困惑。 There are workarounds involving CDATA blocks, but it's easiest simply to avoid using these characters unescaped.有一些涉及 CDATA 块的解决方法,但最简单的方法是避免使用未转义的这些字符。 A better way of writing a script element from script that works on either type of parser would be:从适用于任一类型解析器的脚本编写脚本元素的更好方法是:

 <script type="text\/javascript"> document.write('\\x3Cscript type="text\/javascript" src="foo.js">\\x3C\/script>'); <\/script><\/code><\/pre>"

Here's another variation I've used when wanting to generate a script tag inline (so it executes immediately) without needing any form of escapes:这是我在想要生成内联脚本标记(因此它立即执行)而不需要任何形式的转义时使用的另一种变体:

<script>
    var script = document.createElement('script');
    script.src = '/path/to/script.js';
    document.write(script.outerHTML);
</script>

I think is for prevent the browser's HTML parser from interpreting the <script>, and mainly the <\/script> as the closing tag of the actual script, however I don't think that using document.write is a excellent idea for evaluating script blocks, why don't use the DOM...我认为是为了防止浏览器的 HTML 解析器解释 <script>,主要是 <\/script> 作为实际脚本的结束标记,但是我不认为使用 document.write 是评估脚本的好主意块,为什么不使用 DOM...

var newScript = document.createElement("script");
...

The solution Bobince posted works perfectly for me. Bobince 发布的解决方案非常适合我。 I wanted to offer an alternative method as well for future visitors:我还想为未来的访客提供另一种方法:

if (typeof(jQuery) == 'undefined') {
    (function() {
        var sct = document.createElement('script');
        sct.src = ('https:' == document.location.protocol ? 'https' : 'http') +
          '://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js';
        sct.type = 'text/javascript';
        sct.async = 'true';
        var domel = document.getElementsByTagName('script')[0];
        domel.parentNode.insertBefore(sct, domel);
    })();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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