Credit for this article goes to a discovery by Martin Franklin. Thanks to a comment from him, I discovered something that may be of major importance to folks doing Ajax development on ColdFusion 8 boxes. If you do any work on a ColdFusion 8 box and do not have control over the Administrator settings, beware of the Secure Prefix setting.
About two years ago I blogged about ColdFusion 8 security features. One of them is JSON Prefixes. This is the ability to prefix all JSON results (generated by CFC, returnFormat=json) with a prefix. What's cool about this feature is that all the front end stuff ColdFusion uses will recognize this setting and automatically strip the prefix before processing the result.
What isn't so cool about this feature is that if you aren't using ColdFusion 8's front end AJAX stuff, then this can really trip you up. Imagine you've done all your work locally before pushing the code up to a shared host. All of a sudden your code stops working. It may be a good idea to pop open Firebug and look for something in front (like the default prefix, //) of the JSON response.
Here is a simple example:
<html>
<head>
<script src="jquery/jquery.js"></script>
<script>
$(document).ready(function() {
$("#submitBtn").click(function() {
var value = $("#number").val()
$.getJSON("test.cfc?method=double&returnFormat=json",{number:value},function(d) {
console.log(d)
})
})
})
</script>
</head>
<body>
<input type="text" id="number"> <input type="submit" id="submitBtn" value="Double">
</body>
</html>
Nothing too complex here. I've got a form with one input. When you hit the button, I run an AJAX request to a CFC method that will double the response. The CFC method is just:
<cffunction name="double" access="remote" returnType="any" output="false">
<cfargument name="number" required="true" type="any">
<cfif isNumeric(arguments.number)>
<cfreturn 2*arguments.number>
<cfelse>
<cfreturn 0>
</cfif>
</cffunction>
If you run the code (wrap the cffunction with a CFC of course) it should work just fine. Now go to your ColdFusion Admin, Settings page, and enable the Prefix:
Rerun your code and you will see... nothing. (To be clear, my code did nothing visual with the response except to log it to Firebug, so even before you 'saw' nothing unless you had Firebug open.) I modified my JavaScript a bit to add a global error handler (first time trying this, pretty impressed by how easy it was):
$.ajaxSetup({
error:function(req,textstatus,errorThrown) {
console.log(textstatus)
}
})
Running the page again, I now saw this in the console: parseerror.
Luckily there is a simple fix. You can override the setting (don't forget it can be set in the Application.cfc file as well) by adding the secureJson attribute to the function:
<cffunction name="double" access="remote" returnType="any" output="false" secureJSON="false">
This correctly disabled the prefix and my code worked fine again.
Definitely keep this in mind if you are deploying to machines you don't have 100% control over, or, if things seem to break down when you deploy. (Of course, the first thing to check is for the onRequest method in an Application.cfc file. Sure hope Adobe fixes that in CF9.)