Strange URL Hash Problem With CFLocation In IE6
A little while ago, it was pointed out to me that my Hayden Panettiere Free ColdFusion eCard system was not working in Internet Explorer 6. Because I am working on Windows Vista (and trying every day not to throw the computer out my window), I don't have ready access to IE6. However, since it was working in IE7 and FireFox, I have to admit, I sort of brushed this comment off and didn't pay it much head. However, I finally did get my hands a computer that had IE6 and did some testing. And, sure enough, in IE6, you couldn't get to the Preview eCard screen - it would keep kicking you out to the homepage.
After doing some quick CFDumping of the FORM and URL scopes, the problem was bewildering but obvious; CFLocation didn't seem to be handling URL hash values very well with IE6. To demonstrate what I mean, take a look at this sample code that I set up:
<!--- Check to see if we have the redirect command. ---> <cfif StructKeyExists( URL, "redirect" )> <cflocation url="./index.cfm?id=123##top-of-page" addtoken="false" /> </cfif> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Untitled</title> </head> <body> <h1> Redirect Test With URL Hash </h1> <p> <a href="./index.cfm?redirect">Redirect with hash</a> </p> <!--- Dump out URL scope. ---> <cfdump var="#URL#" label="URL Scope" /> </body> </html>
Here, we are providing a link that will trigger a CFLocation tag. That ColdFusion CFLocation tag has both an URL parameter (ID) and a hash value (#top-of-page). When this CFLocation is triggered in FireFox, it acts as expected and the proper ID value is moved to the URL scope:
However, when this page is run in IE6, we get the following output:
Notice that the hash value (#top-of-page) is read out of the URL as part of the ID parameter. This is the strangest bug! I have no idea why this is happening and why it only happens in IE6?!? Hash values are part of the HTTP protocol, are they not? Am I just not seeing something very obvious in the code? This must be a bug in IE6... but then again, why would it have any affect on ColdFusion? These two applications are running in totally different places.
To fix this, I simply put an ampersand before the hash:
<cflocation url="./index.cfm?id=123&##top-of-page" addtoken="false" />
This works fine and doesn't add any extra values to the URL scope. Strangest thing. Does anyone understand why this would be happening?
Want to use code from this post? Check out the license.
I run IE6 side-by-side with IE7 http://tredosoft.com/Multiple_IE
I appreciate the link, but that tool does not work on Windows Vista (Ahhhh!)
VmWare is free, but of course means a whole seperate Windows install just for IE6.
I appreciate that. Feels like a little too much effort :)
But, really, let's not lose the point of this post. The issue is not how to test in IE6, it's that ColdFusion seems to mishandle the URL when passed from IE6. This seems extremely strange to me.
Could you sniff the HTTP traffic, and verify CF is sending the exact same request to both browsers when you use cflocation ?
Not sure I know how to do that?? Is that easy?
Wireshark is dead easy, works on Linux and Windows. Probably Macs for all I know.
Other people swear by Charles (which hijacks the Windows proxy settings automatically) or Fiddler.
I use Service Capture....
This is very odd. I just tested on our local server and there's the same issue. Definitely an IE6 bug... which will never be fixed :/ Good thing to know there's a work around.
Yeah, that is totally where I was getting that terminology (from the location object) :)
Thanks for double-checking this. Good to know it's not just my machine or something. I wonder what it is about IE6 that is making the problem? Wouldn't CF know to parse the URL???
here's a link to a IE6 testing tool that works on Vista ;-)
This looks awesome. Thanks!
I don't think it's CF that's not parsing the URL, it's the web server, and I'm not really sure that's the issue either. The browser is supposed to strip the fragment identifier off the URL before it sends it to the server, and in this case it isn't, and I'm not really sure what the defined behavior is for web servers.
I have seen this used as a way to block spambots since a lot of time they send the fragment identifier to the server so you can block them that way. I guess that wouldn't work here.
Also, I don't believe that HTTP actually mentions fragment identifiers at all. It's part of the URI/URL RFC so there's some issues of what you're really supposed to do. Seems there's even some issues with how to handle redirects as a result: http://www.w3.org/Protocols/HTTP/Fragment/draft-bos-http-redirect-00.txt
I'm guessing that this is why I long ago developed a habit of setting URL parameters that subsequently executed JS calls to do a jump after a redirect. Nice to know I don't have to do that anymore in IE 7.
What I mean is the following:
Then on the 'whatever' page, at the bottom:
<cfif structKeyExists(url, "jump)>
location.hash = <cfoutput>"#url.jump#";
or something along those lines. Works like a champ, but it ain't clean.
P.S. Yeah, I spent several months coming within inches of blowing away my new Vista machine and re-installing XP ... only thing stopping me from doing it was uncertainty about new hardware drivers for XP.
Not sure if this will help your development environment or not, but I'm a Vista user and have been running MS Virtual PC 2007 with an XP sp2 IE6 virtual pc image (which is set to expire on June 3rd) both of which are free. They even have an IE8 image available too.
Virtual PC 2007: http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx
XP sp2 IE6 virtual pc image: go.microsoft.com/fwlink/?LinkId=70868
Yes I'm still supporting IE6 and this came in handy today ... it was starting to annoy me, but as always it's usually a simple solution! ... Thanks man! ... I know this thread is from a while back, but on a side note I use IETester to test previous version of IE just in case anyone is looking for a way to test without having to use Virtuals or older PCs.