20

I was wondering why ad's still use the document.write approach to inserting the add into the page

<script language="javascript" type="text/javascript">
    document.write("<script type='text/javascript' src='http://addomain/someadd.js'><\/sc" + "ript>");
</script>

Why is it that I can't just put

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

In place of the ad?

Ry-
  • 218,210
  • 55
  • 464
  • 476
James Hughes
  • 6,194
  • 4
  • 31
  • 44

9 Answers9

8

A traditional script tag will block the page while it is loading and executing. A script loaded with document.write will work asynchronously. That's why you see this on ads or analytics, as such scripts don't influence the page content directly.

Christophe
  • 27,383
  • 28
  • 97
  • 140
  • That's not true, you can access the content of the script tag added with a `document.write` immediately, as long as it's from a new script tag, unless you specify defer=true [Here's the proof](https://jsfiddle.net/mendesjuan/eymsv7qc/) That's why you use `document.write` when you need add some dynamic parameters to the script but don't want to deal with async loading of creating a script node. – Ruan Mendes Feb 17 '17 at 23:20
  • 1
    What about – Marek Nov 18 '17 at 00:07
5

I work with a web advertising company, and from what I've heard, certain browsers (don't know off hand which ones) will allow you to drop script tags into the page, but won't allow you to automatically execute their contents.

So, to pull this off, you need to break the script tag into pieces so the browser doesn't treat it as a script tag, but rather as any old HTML Data. Then, as the DOM is processed serially, the next thing it evaluates, after writing out the script tag is... hey, that script tag you just wrote out.

At this point the script tag is evaluated and executed.

Paul Sweeney
  • 322
  • 3
  • 7
  • Not sure I grasp this one. I can;t see how it would be treated differently. – James Hughes Sep 03 '09 at 07:38
  • 1
    Our company received similar code from an advertising company. I agree with Paul - it's basically a method of reducing the liklihood that the script is filtered/ignored. – Mayo Sep 23 '09 at 16:57
  • 1
    I should also add that the code we recieved was further obfuscated with concatenation... ""... made it pretty obvious that's what they were doing. – Mayo Sep 23 '09 at 17:01
5

Often these document.write injected scripts have dynamic strings attached to them to bust out of caching, or to send some info about the client to the ad server. I suspect your example started out as something like this

document.write("<script type='text/javascript' src='http://addomain/someadd.js?"+extrastuff+"'><\/sc" + "ript>");

but got tweaked over time, or was copied and modified by someone who didn't understand the extrastuff bit. But as you've written it there is no difference: the two ways you cite in your question are functionally the same.

Michael Mathews
  • 481
  • 4
  • 9
2

I stand corrected, doc.write created scripts are blocking - worse than I though heh :) - but as an adblock avoider it's really weak, so I can only conclude it's an SOP mechanism for dynamically adding params to a script request overused.

Use the DOM insertion technique when avoiding script blocks kids.

annakata
  • 74,572
  • 17
  • 113
  • 180
  • This is what I thought but considering it makes page rendering slower in in all my tests I can't believe this is actually true. Inline scripts and even appending it to the DOM manually all produce faster renders (in fact document.write make a signifigant block compared to the rest). – James Hughes Feb 17 '09 at 11:56
  • @annakata: Do you have a link which explains this with more details? I also have doubts about the "circumvent blocking". – Aaron Digulla Feb 17 '09 at 12:17
  • No, it's something I'm involved in professionally - I've seen competitors invoking doc.write techniques and had assumed it was part of a blocking solution (since the rest of the code fits the common pattern). Turns out doc.write is just *really* bad, and I'm giving the competition too much credit :) – annakata Feb 17 '09 at 12:31
1

This method avoids loading the external script if active scripting is disabled.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 2
    if scripting is disabled no scripts are loaded anyway - at least in FF, haven't tested elsewhere but I believe this is true – annakata Feb 17 '09 at 12:51
  • At least some older browsers did that. – Gumbo Feb 17 '09 at 13:13
  • So you mean if active scripting is disabled it prevents the file from loading? Where as if it where a script tag it would be loaded (but not executed)? – James Hughes Feb 17 '09 at 14:27
  • 1
    I don’t know it exactly. But I think there are some browsers that do load external script files although active scripting is disabled. So using the former variant would prevent those browsers from loading the external script file. – Gumbo Feb 17 '09 at 15:00
  • That seem to be complicating matters just for the sake of preventing some (probably) legacy browsers downloading a single ad. I can't imagine that's the only reason! – James Hughes Feb 18 '09 at 09:32
  • I don’t think that’s the reason either. (Since when do advertiser care about us?) But it’s a nice side effect. – Gumbo Feb 18 '09 at 10:28
0

IMHO, that's not only pointless, but even incorrect. Angle brackets are not escaped, which'll render document technically invalid HTML (even though it'll work in all major browsers, because they try to recover from coders' errors). And in case one's serving his site with XHMTL pages as application/xml+xhtml, document.write() just won't work at all.

drdaeman
  • 11,159
  • 7
  • 59
  • 104
  • Angle brackets don’t need to be escaped in ``, usually escaped in strings as `<\/script>` or ``, etc.. Also, since when doesn’t `document.write` work in XHTML? – Ry- Jan 15 '14 at 21:15
  • @minitech : You're wrong on both points. In XHTML `script` element is [defined](http://www.w3.org/TR/xhtml1/dtds.html#dtdentry_xhtml1-strict.dtd_script) as `<!ELEMENT script (#PCDATA)>` in DTD - see yourself, it's [PCDATA, not CDATA](http://stackoverflow.com/a/918464/116546). One usually uses `<![CDATA[...]]>` instead of manual entity encoding, though. And `document.write` does not exist for `XMLDocument`s, so it [never ever worked](http://is.gd/VymCN5) unless you incorrectly served XHTML as `text/html`, instructing the browser to treat is as HTML. – drdaeman Jan 16 '14 at 21:46
  • Have browsers ever treated XHTML documents differently DOM-wise, though? (i.e. as an XML document?) That’s news to me. Anyways, “angle brackets don’t need to be escaped in ` – Ry- Jan 16 '14 at 21:48
  • Yes, if served with correct MIME type documents are parsed with XML. Have you ever seen that yellow "XML parse error" page in Firefox? http://xhtml.com/en/xhtml/serving-xhtml-as-xml/ Personally, I've seen it a dozen of times when XHTML was a hip and everyone tried to use it. – drdaeman Jan 18 '14 at 11:00
0

I don't know for certain, but they might use it so all the content on the website is loaded and shown to the user first, then the ads are loaded and shown.

Hoffmann
  • 14,369
  • 16
  • 76
  • 91
0

To match this with regex and to remove is easy :

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

but the other is more complex and can be written in different formats.

I think this is the reason.

Canavar
  • 47,715
  • 17
  • 91
  • 122
-2

A way to make it somewhat less likely their add is blocked.

Alex Bridges
  • 67
  • 1
  • 2
  • 10
  • Does it though? Because the execution ultimately results in a call to the same endpoint via the same mechanics which an ad blocker would still block. – James Hughes Jan 16 '14 at 08:48