为什么要使用document.write?

20

我想知道为什么广告仍然使用document.write方法将广告插入页面

<script language="javascript" type="text/javascript">
    document.write("<script type='text/javascript' src='http://addomain/someadd.js'><\/sc" + "ript>");
</script>
为什么我不能只是输入

呢?
<script type='text/javascript' src='http://addomain/someadd.js'></script>

取代广告的位置?


1
这里有一个有趣的重复圆形。 - Ry-
9个回答

8

传统的脚本标签会在加载和执行时阻止页面。使用document.write加载的脚本将异步工作。这就是为什么你在广告或分析中看到这样的脚本,因为这些脚本不会直接影响页面内容。


这是不正确的说法,只要是从新的 script 标签中通过 document.write 添加的内容,除非指定 defer=true,否则可以立即访问。这里有证据。这也就是为什么当您需要向脚本添加某些动态参数但不想处理异步加载或创建脚本节点时,使用 document.write - Ruan Mendes
1
那么<script async>呢? - Marek

5
通常这些由document.write注入的脚本会附加动态字符串,以打破缓存或向广告服务器发送有关客户端的一些信息。我怀疑你的示例最初是这样的。
document.write("<script type='text/javascript' src='http://addomain/someadd.js?"+extrastuff+"'><\/sc" + "ript>");

但随着时间的推移,它可能被微调,或者被一些不理解“额外内容”部分的人复制并修改。但是按照您所写的方式,没有区别:您在问题中引用的两种方式在功能上是相同的。


5
我在一家网络广告公司工作,据我所知,某些浏览器(不确定是哪些)允许您将脚本标记放入页面中,但不允许您自动执行其内容。
因此,要实现此操作,您需要将脚本标记分解成多个部分,以便浏览器不将其视为脚本标记,而是视为普通的HTML数据。然后,在DOM按顺序处理时,它写出脚本标记后,下一件要评估的事情是...嘿,你刚刚写出的那个脚本标记。
此时,脚本标记将被评估和执行。

我不确定我理解了这个问题。我无法看出它会被如何区别对待。 - James Hughes
1
我们公司从一家广告公司收到了类似的代码。我同意Paul的看法——这基本上是一种减少脚本被过滤/忽略的可能性的方法。 - Mayo
1
我还应该补充一点,我们收到的代码还被串联起来进一步混淆了... "<scr" + "ipt>"... 这让人很明显地知道他们在做什么。 - Mayo

2

我错了,doc.write创建的脚本是阻塞的 - 比我想象中还要糟糕,哈哈 :) - 但作为一个广告拦截器的避免者,它真的很弱,所以我只能得出结论,这是一种过度使用的SOP机制,用于动态添加参数到脚本请求中。

当避免脚本块时,请使用DOM插入技术。


这是我原本的想法,但考虑到在我的所有测试中它都会使页面渲染变慢,我无法相信这是真的。内联脚本,甚至手动将其附加到DOM中,都能产生更快的渲染效果(事实上,与其他部分相比,document.write会造成显著的阻塞)。 - James Hughes
@annakata:你有更详细的解释链接吗?我也对“规避阻止”有疑问。 - Aaron Digulla
不,这是我职业上涉足的领域 - 我曾看到竞争对手调用doc.write技术,并认为它是阻塞解决方案的一部分(因为其余代码符合常见模式)。结果发现,doc.write实际上非常糟糕,我给了竞争对手太多的信任和赞誉 :) - annakata

1

如果禁用了活动脚本,则此方法避免加载外部脚本。


2
如果脚本禁用,则无论如何都不会加载脚本 - 至少在FF中是这样,尚未在其他地方进行测试,但我相信这是正确的。 - annakata
至少一些旧版浏览器会这样做。 - Gumbo
那么您的意思是,如果禁用了活动脚本,则会阻止文件加载?而如果它是一个脚本标签,它将被加载(但不会被执行)? - James Hughes
1
我不确定。但我认为有一些浏览器即使禁用了活动脚本,仍然会加载外部脚本文件。因此使用前一种方式可以防止这些浏览器加载外部脚本文件。 - Gumbo
这似乎只是为了防止一些(可能是)旧版浏览器下载单个广告而使事情变得复杂化。我无法想象这是唯一的原因! - James Hughes
我也不认为那是原因。(广告商何时关心过我们呢?)但这是一个好的副作用。 - Gumbo

0

使用正则表达式匹配并删除很容易:

<script type='text/javascript' src='http://addomain/someadd.js'></script>

但另一个更复杂,可以用不同格式编写。

我认为这就是原因。


0

在我看来,这不仅是毫无意义的,甚至是错误的。角括号没有被转义,这将使文档在技术上无效的HTML(尽管它在所有主要浏览器中都可以工作,因为它们试图从编码人员的错误中恢复过来)。而且,如果有人使用XHMTL页面作为application/xml+xhtml提供他的网站,那么document.write()根本就不起作用。


尖括号在<script>块中不需要转义 - 实际上,这样做会导致它们失败得相当严重。唯一需要考虑的是 </script>,通常在字符串中转义为 <\/script></scr" + "ipt> 等等。另外,自从什么时候开始在XHTML中document.write无效了? - Ry-
@minitech:你两点都错了。在XHTML中,script元素在DTD中被定义为<!ELEMENT script (#PCDATA)>-请自行查看,它是PCDATA而不是CDATA。虽然可以手动实体编码,但通常使用<![CDATA[...]]>。并且XMLDocument不存在document.write,所以它从来没有工作过,除非你错误地将XHTML作为text/html提供,并指示浏览器将其视为HTML。 - drdaeman
浏览器是否曾经以不同的DOM方式处理XHTML文档,例如作为XML文档?这对我来说是新闻。无论如何,“在<script>块中不需要转义尖括号”是正确的。我当时并没有谈论XHTML。(你的回答似乎也不是关于XHTML的。) - Ry-
是的,如果使用正确的MIME类型提供文档,则会解析XML。你是否在Firefox中看到过那个黄色的“XML解析错误”页面?http://xhtml.com/en/xhtml/serving-xhtml-as-xml/ 就我个人而言,在XHTML很流行并且每个人都试图使用它的时候,我已经见过它十几次了。 - drdaeman

0
我不确定,但他们可能会使用它,以便在用户首先加载和显示网站上的所有内容,然后再加载和显示广告。

不 - 起初我也是这么想的,但是doc.write创建的脚本确实会阻塞。 - annakata

-2
一种使广告被屏蔽的可能性稍微降低的方法。

它真的会吗?因为最终执行结果仍然通过相同的机制调用相同的端点,而广告拦截器仍然会阻止它。 - James Hughes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接