Posted in JavaScript, ColdFusion | Posted on 10-22-2008 | 3,090 views
I ran into an interesting JavaScript issue yesterday. A user reported a bug with ColdFusionBloggers and searching. If he searched for one word, like 'object', then he could navigate through multiple pages of results just fine. If he search for two words, 'object oriented', then as soon as he clicked next the page would break.
This immediately made me think that I had forgotten a urlEncodedFormat() call somewhere. I'm very good about remembering that but it was certainly possible I could have made a mistake. (Although I'd probably blame Microsoft somehow.) When I opened the file though I could plainly see that I was indeed urlEncodeFormating the string before passing it to my JavaScript code to handle navigation.
I wanted to blame jQuery for this. When you use jQuery to do an Ajax-based content load into a div, they support loading a URL and optionally filtering to a div. What I mean is, you can say: I want you to load the contents of foo.cfm into my div called content, however, I don't want you to load all of foo.cfm, I want you to load the goo div's content only.
Here is an example that does a plain load of foo.cfm, and then another one that loads the goo div from foo.cfm:
2
3versus...
4
5$("content").load('foo.cfm goo')
Notice that the syntax uses a space to signify that the goo div is what we want from foo.cfm. My code was passing a URL that looked something like this:
content.cfm?start=11&search=foo%20goo (a search for foo goo)
Notice the escaped space. I thought perhaps jQuery was un-encoding the string somehow and getting confused. However, as I dug more, it seemed more as if that the string was being undecoded as it arrived to the function. I was able to recreate this bug without any jQuery at all:
2<cfset u = "test3.cfm?x=1&foo=#urlEncodedFormat(s)#">
3
4<script>
5function testit(s) { console.log(s); }
6</script>
7<cfoutput>
8<a href="javaScript:testit('#u#')">Test1</a><br />
9<a href="" onClick="testit('#u#');return false">Test2</a><br />
10</cfoutput>
So get this. Notice how the first link uses a javaScript: style link while the second uses an onClick. When you run this test, the first one will log test3.cfm?x=1&foo=frank. No beans! Edit: I had a brain fart there. The console shows frank and beans, but w/o the %20, the escape. End Edit The second test will correctly show the entire string with the proper escape values. I also tested with an input type=button and it worked fine as well.
So for some reason, when the string was passed using the href property of the anchor, the encoded part of the string is lost somehow. Now I'm still getting used to JavaScript after my long, dark, cold war with it, and I believe that I've read the using the event handler way is 'more proper', but this is the first time I've been bitten by something like this.
Does anyone know of any place where this behavior is documented?


If you don't go the event handler approach that should solve your problem.
If you replace console.log(s) by alert(s), you'll see the difference.
I agree, it's weird.
The console.log DOES show frank and beans, but WITHOUT the escape. Brain fart on my part. Still wrong for sure.
Anyway, the alert shows the same as the console msg for me.
@JD - For CFB, I just used replace and switched spaces to +. I didn't notice the 'nicer' event handler fix till later.
Have you tried to see if setting the encoded var into a js var makes a difference before adding it to the href?
<cfset s = "frank and beans">
<cfset u = "test3.cfm?x=1&foo=#urlEncodedFormat(s)#">
<cfoutput>
<script>
function testit(s) { alert(s); }
var s = '#s#';
var u = '#u#';
</script>
<a href="javaScript:testit(u)">Test1</a><br />
<a href="" onClick="testit(u);return false">Test2</a><br />
</cfoutput>
I haven't found any mention of a problem such as this before, the only thing I can think of is that the string is getting parsed improperly when it's first initialised in the JS engine, although it's strange that putting it into a javascript variable works.
Seems to show the same behaviour in different browsers.
Its probably the browsers HTML engine since the string is being added to the href property. that would make since because its being evaluated before its passed to the JS engine.
Tim
Not sure what else we can do to get to the bottom of it really.. it's strange it's not documented anywhere?
javaScript:testit('-%20-')
Its automatically unencoding the url for use.
[Add Comment] [Subscribe to Comments]