Protect IE from empty img src
In a previous post, I discussed the problem with setting an HTML image’s src attribute to an empty string. In Internet Explorer, Safari, and Chrome, this results in a second request being made to the server (Firefox 3.5 patched this behavior and Opera doesn’t exhibit the behavior). My post also showed a couple of ways to detect this issue on the server side at the time a request is received. I noted that it’s very difficult to detect these requests from Internet Explorer because it doesn’t send different Accept headers for image requests than it does for HTML requests. After a bit more investigation, I’ve found a way to prevent this behavior in Internet Explorer through version 8.
The <base> tag
I’m still not entirely sure why this is true, but if you specify a base URL in the page using the <base> tag. For those unaware, the <base> tag is used to alter how URLs are resolved and linked to within a page. The href attribute is used to indicate the base URL from which relative URLs on the page should be resolved. This affects not just the <a> tag, but also any tags that accept a URL as an attribute value. Consider the following:
<img src="smile.gif">
To resolve smile.gif for this tag, the browser looks at the path of the containing page and then append smile.gif. So if the page is http://www.nczonline.net/blog/, then the image is resolved to http://www.nczonline.net/blog/smile.gif. This is how normal URL resolution works. Adding a <base> tag alters the default URL resolution. Example:
<html> <head> <base href="/stories/"> </head> <body> <img src="smile.gif"> </body> </html>
If this page has a path of http://www.nczonline.net/blog/, then the image’s URL is resolved to http://www.nczonline.net/stories/smile.gif. That’s because the base URL is reset to http://www.nczonline.net/stories/ by the <base> tag, so all URLs on the page are now resolved relative to that address. This is a convenient way to avoid duplicating the same URL information for every link on the page.
The approach
For some reason that I still don’t understand, the act of setting a base URL on a page causes Internet Explorer to ignore any <img src=""> that appears on the page, including <input type="image" src="">. As long as a <base> tag appears on the page with an href specified, IE will no longer make a request to the server when one of these tags is present. You can try this yourself by viewing HTTP traffic while loading the following two pages (I recommend Fiddler):
If you have the possibility of an empty string image URL on your page, it would serve you well to set the base URL for the page. Since you probably don’t want to actually change how the URL is resolved, just set the base URL to the current path for the page. In PHP, you can use this code:
echo "<base href=\"{$_SERVER['REQUEST_URI'];}\">";
That way, you’re including the base URL to avoid the extra image request without changing how all URLs on the page are resolved.
Conclusion
Specifying a base URL on a page is a quick and easy solution to prevent an extra request due to an empty image source URL in Internet Explorer. It’s important to note that this has no effect on the other browsers with this behavior. For those, you’ll still have to use the server-side detection logic shared in the previous post to detect such a request and abort before server resources are used. At least for Internet Explorer, the solution is simple and can save your server.
Credits
Although I started running tests with this as part of an investigation based on a WHAT-WG mailing list discussion, Ben Alman hinted at this solution in a tweet to me that I apparently missed. Had I been paying attention, this would have been a much faster followup!
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




9 Comments
I love how my tweet makes me sound like a 14-year old girl, awesome!
"Cowboy" Ben Alman on December 22nd, 2009 at 1:33 pm
The <base> tag unfortunately creates some other crazy problems in IE6… I would highly recommend against using it… The bug is that the tag is treated as an unclosed tag (even if you explicitly close it), which means IE treats it as the parent tag for all the rest of the HTML content (including the entire <body>). This can wreak havoc with JavaScript that is adding and removing elements from the DOM. \
jQuery for instance has a workaround in place which when doing JSON-P script tags, it insertBefore()s them to the head (in front of a base tag) instead of appendChild(). This merely ends around the problem by forcing the script tag to be part of the <head> in front of where the offending <base tag is. But it’s not at all a solution for the fact that IE6 really behaves poorly with <base>.
Kyle Simpson on December 22nd, 2009 at 2:56 pm
@Kyle – that’s interesting, though it sounds like the case you’re worried about is if you have <base> in the <body>, is that correct? If so, does placing it in <head> fix this?
Nicholas C. Zakas on December 22nd, 2009 at 3:29 pm
Your message didn’t come through the formatting very well, but i did view-source to see what it was you said. For posterity sake, the actual question is:
@Kyle – that’s interesting, though it sounds like the case you’re worried about is if you have <base> in the <body>, is that correct? If so, does placing it in <head> fix this?
Actually, the precise problem I was referring to is including the <base> tag in the <head> of the document… in IE6, whether you close it or not, the browser will interpret it as an unclosed tag, and “swallow” up everything after it in the markup.
The problem with using it is that you may cause scripts which aren’t aware of this bug to inadvertently fail if they are trying to add/remove nodes from the <head>, like code which adds <script> nodes… such as the JSON-P requesting in jQuery. Another example of code that would fail would be script loaders. LABjs, my script loader, for instance was vulnerable to this problem until the patch release I did this morning, in fact.
As I said before, instead of doing “head.appendChild(obj)”, the workaround currently is to do “head.insertBefore(obj,head.firstChild)”. This just avoids the problem by making sure the scripts are added to the very beginning of the <head>, ahead of the <base> tag.
But it’s a bad fix, because it spec says that nothing should appear before the <base> tag, and also having the <script> nodes added in the reverse order can cause issues too. And it does nothing to address objects that are added/removed from other parts of the DOM and thus swallowed by the <base>. As I said, until a better fix is found, I would personally not recommend the use of <base> tag for pages that need to work correctly in IE6.
Kyle Simpson on December 22nd, 2009 at 7:08 pm
Fascinating, thanks for the heads up. I admit I tried IE7 and IE8 but neglected our old friend IE6. I’ll have to play around with that some.
Nicholas C. Zakas on December 22nd, 2009 at 11:05 pm
Actually, the tag causes issues for me in IE7 (and that was placing it in the as well). It completely screws up trying to load scripts in parallel without blocking (ala Steve Souders instruction). This was a problem not only with a slight variation on the Steve Souders “Script DOM Element” method but also using LABjs! And it completely resolved itself once once I removed the tag??
If anyone knows why this would happen then I would be very interested to hear about it
Mark McDonnell on February 6th, 2010 at 6:17 pm
corrections (seems the HTML tags were stripped out, my bad)…
“…the *base tag causes issues…”
and
“…that was placing it in the *head as well…”
Mark McDonnell on February 6th, 2010 at 6:19 pm
Can value of the SRC attribute of the HTML IMG tag = one Image file stored in another machine of a LAN.
Secondly, can the path of the image reffered in the src attribute of the IMG tag = the path referrs to another directory other than the mapped to IIS where image is stored.
surjit on July 16th, 2010 at 10:49 am
[...] 2009年11月22日 Protect IE from empty img src [...]
ゆã£ãりã¨â€¦ » JavaScriptã®”Lazy Loading”ã¨ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°æ™‚間を検証ã™ã‚‹ on October 23rd, 2010 at 10:57 am
Comments are automatically closed after 14 days.