Tuesday, March 08, 2005

Script Tag In Internet Explorer

After a sleepless night or two, I just discovered this bug in Internet Explorer the hard way.

I was bascially including a JavaScript file in my XHTML document. The scripts in this file were meant to attach to my XHTML elements unobtrusively, and this file was a unit by itself. So I didn't have any JavaScript within my script tags. This is how my tag looked.

<script language="javascript" type="text/javascript" src="script.js" />

This works like a dream everywhere, except in the world's most popular browser. In IE, the entire page is just blank! The markup is downloaded properly (I can see it when I view source), even my CSS background-color is applied to the page, but there's absolutely nothing on it! I blamed my content-negotiation scripts first (I am serving HTML Transitional to IE and XHTML everywhere else), and then on IE's support for CSS (I thought I made a grave little mistake somewhere). However, on removing this tag, everything worked fine in IE.

Turns out, IE doesn't like the script tags if they are using element minimization. I got the page rendering just as I intended by changing the tag to look like this:

<script language="javascript" type="text/javascript" src="script.js"></script>

Doing some research, I came across this post in theList by Eric Vitiello which clarifies this more. Apparently the DTD declaration for the script tag says <!ELEMENT script (#PCDATA)>, and the XHTML specs says (under Appendix C. 3):

Given an empty instance of an element whose content model is not EMPTY (for example, an empty title or paragraph) do not use the minimized form (e.g. use <p> </p> and not <p />).
So, I guess this isn't really a bug in IE. I'd think instead, that this is a bug in the DTD itself. The script tag doesn't have to contain #PCDATA (in fact, I consider it graceful if it doesn't), and forcing it is, well, stupid.

For now, I am explicitly closing the script tag with a seperate closing tag, and everything seems to be working well. Does anyone have any idea about handling this better, preferably with minimized element closures?


Rakesh Pai said...

Thanks, Charl, for that info.

I tried this with Opera too. Here's my results.

With <script> </script> and "text/html":
IE - renders fine.
Opera - renders fine.
Firefox - renders fine.

With <script /> and "text/html":
IE - chokes up.
Opera - chokes up.
Firefox - renders fine.

With <script> </script> and "application/xhtml+xml":
IE - (tch tch)
Opera - renders fine.
Firefox - renders fine.

With <script /> and "application/xhtml+xml":
IE - *sigh*
Opera - renders fine.
Firefox - renders fine.

Obviously, <script> </script> is the only reliable piece of working code, irrespective of the doctype.

What confuses me is, how does Firefox work fine with <script /> while Opera chokes, when served with "text/html"? If Opera is right, so is IE, and Firefox is wrong. If Firefox is right, Opera is wrong.

How does the minimized element representation mean different things with different content-types? Considering that different browsers handle it differently, what is the correct implementation?

Anonymous said...

This is not a bug at all. When you are serving a document as text/html, which you're probably doing since IE tries to render it, a user agent must interpret it as HTML. The <script/> syntax is not valid HTML (it's actually the same as <script>>, although virtually all browsers get that wrong). The closing tag is not optional for the SCRIPT element.

Anonymous said...

I too had been having the same problem. Thanks for clearing it up.

Anonymous said...

Wow, over a year later and this is the only mention of this issue I have found on the Internet.

Thanks for helping me figure this annoyance out.

Anonymous said...

If the XHTML DTD classified the script element as EMPTY you would be unable to use embedded scripts because embedding scripts would be prohibited. It is definitely not what you want.

Anonymous said...

Jeez, that one would have taken me forever. Thanks for bearing the pain for us all.

Rakesh Pai said...

Hey Christopher,

What I meant was that the script tag should be optionally empty, like it is completely logal to have an empty <p /> tag.

Anonymous said...

Thank you for the explanation; it's excellent!

Anonymous said...

Heh, now Firefox 3.0 Beta 2 has the same problem, or shall I say the feature :)

It breaks if the <script> tag is closed on its own and the content-type is text/html.

Need to check with a different content-type.

I noticed it today when one of our internal apps I wrote suddenly stopped working.


Will Shaver said...

Thanks, solved my headache.

Anonymous said...

Another gotcha in IE. My script tag's type attribute had a trailing space: <script type="text/javascript "> which it probably shouldn't. FF loaded the script anyway, but IE barfed.

Alexei said...

This is really weird, im glad i found this out, i am using google analitycs and i was worried that i was just seen less than 10 visits per day for the last 3 days, when was i getting 100+ daily (This is a single page site (flash))