131

Example from Googles +1 button:

<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
      {"parsetags": "explicit"}
</script>

The script Tag has a src-Attribute and content. What does this mean and how does it work?

usr
  • 168,620
  • 35
  • 240
  • 369

4 Answers4

73

Different browsers treat this differently. Some run the content only if the src is included without error. Some run it after attempting to include the src script, regardless of success. Since this behaviour is unreliable (and prohibited in HTML5), it should be avoided.

Google isn't relying an any specific behaviour. Since the content is just an object literal (a value), executing it would not actually do anything except cause a silent error. Google's code looks at the contents of the script tag itself, and adjust its behaviour based on that.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • 3
    Is there a cleverer way for the script to look at the contents of its own script tag (specifically), than going through the DOM? – Karl Knechtel Jun 29 '11 at 23:17
  • 15
    On all browsers I've worked with, the script content will never be executed if the `src` attribute is present, and actually is not really an object literal, that code would produce a `SyntaxError` if executed, it's simply "JSON text" that the script will use by itself later. – Christian C. Salvadó Jun 29 '11 at 23:17
  • 2
    @Karl used within an external .js file, this will give you the contents of the currently executing – digitalbath Jun 30 '11 at 02:26
  • @CMS works on all browsers except IE. You can see it [here](http://jsfiddle.net/EjfPM/) – Jose Faeti Sep 07 '11 at 09:15
  • 3
    @jose - your example is not what CMS was refering to. If the code is run as a stand alone statement, it is a syntax error. Your example (and Google's) "works" only because the content of the script element is ingnored due to the *src* attribute. – RobG Oct 25 '11 at 00:19
  • @JeremyBanks: "If you can't explain it simply, you don't understand it well enough." - Albert Einstein ...I didn't understood a single word and I believe you do not know it yourself well. Sorry, definitely not hurting you. – Jasmine May 23 '14 at 07:09
  • 3
    @KarlKnechtel - try: `document.currentScript` inside your 'src' referenced script to get a reference to the script's own ' – Daniel Sokolowski Feb 11 '15 at 02:36
  • `{"parsetags": "explicit"}` isn’t an object literal. An object literal is an expression, which must be an expression statement, but expression statements cannot begin with `{`. `{"parsetags": "explicit"}` is invalid syntax if parsed as a script or a module. – Sebastian Simon Jun 16 '21 at 14:34
28

If a script element has a src attribute, the content must be ignored, any other behaviour is non-conformant.

It has been suggested in blogs (as a hack) to put content in the element knowing that it won't be evaluated, then use DOM methods to get the content as a string and either eval it or insert it in a new script element. Neither of these are a good idea.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • 5
    Why is this not a good idea? What if it's used to initialize a third party plugin? – thekingoftruth Mar 05 '14 at 19:41
  • 1
    Old thread but to answer @thekingoftruth's question: html is editable by clients, so run it through eval means giving the user the ability to run arbitrary code, which is a massive security vulnerability. – theberzi Sep 21 '20 at 20:05
  • @FedericoS—users have the ability to run arbitrary code anyway, I don't see an eval approach as much of a security issue *per se*. It's more just untidy and inefficient given there are much more elegant ways to optionally load code, though it's been popular for some time to just dump everything plus the kitchen sink into the first page and hope caching delivers some efficiencies thereafter. E.g. the home page at Qantas is 24 mB. – RobG Sep 21 '20 at 23:45
15

After the script has loaded, it looks inside its own script tag to access its content.

It will use some code similar to this:

var scripts = document.getElementsByTagName("script");
var data = eval(scripts[scripts.length - 1].innerHTML);

Courtesy of John Resig.

James Billingham
  • 760
  • 8
  • 32
13

According to the HTML5 draft specification, <script> elements with src attributes should only have commented-out code, which is intended to give documentation for the script. It doesn't appear as though Google is conforming to this specification though.

Jim
  • 72,985
  • 14
  • 101
  • 108