When not to use cfcontent

Here’s an interesting problem (that most of you will be able to guess the answer to because of the title) a reader ran into. He had a very simple form that took in your input and saved it to an XML file. The problem he had was in how to let the user know the file was generated. Sounds simple enough, but take a look at his code and see if you can figure out the problem.

<cfset showForm = true> <cfif structKeyExists(form, "name") and len(trim(form.name))> <cfprocessingdirective suppresswhitespace ="Yes"> <cfcontent type="text/xml; charset=utf-16"> <cfxml variable="packet"><cfoutput><person><name value="#xmlFormat(form.name)#" /></person></cfoutput></cfxml> <cfset fileWrite(expandPath("./test.xml"), toString(packet))> </cfprocessingdirective> <cfset showForm = false> </cfif> <cfif showForm> <form method="post"> Name: <input type="text" name="name"> <input type="submit" value="Save"> </form> <cfelse> <p> Thanks for sharing your name. The Men in Black will be over soon. </p> </cfif>

Reading top to bottom, you can see my form handling portion on top. If the user entered a name (and the validation here is pretty simple, it should look for an empty string to be complete), it takes that name value and creates an XML variable from it. It then records it to a file, test.xml, and sets a flag to let the user know the process is done. But notice the output (in Chrome at least):

Woah - hold the chickens there. What happened? Well the issue is the use of cfcontent. The reader had probably seen that many times before. What he didn't realize is that it was being used to serve XML to the user. cfcontent is like a special way to warn the browser. Instead of getting HTML back, cfcontent tells the browser something like this:

"Hey buddy, I know you are expecting some HTML back, but I've got a truck load of something else. It kind of smells like XML, so let's just say it's XML."

When given this "hint", the browser can then try to handle it better. It's pretty much always required for binary data, and should be used for non-HTML responses, like XML and JSON. Removing the cfcontent fixes everything.

<cfset showForm = true> <cfif structKeyExists(form, "name") and len(trim(form.name))> <cfprocessingdirective suppresswhitespace ="Yes"> <cfxml variable="packet"><cfoutput><person><name value="#xmlFormat(form.name)#" /></person></cfoutput></cfxml> <cfset fileWrite(expandPath("./test.xml"), toString(packet))> </cfprocessingdirective> <cfset showForm = false> </cfif> <cfif showForm> <form method="post"> Name: <input type="text" name="name"> <input type="submit" value="Save"> </form> <cfelse> <p> Thanks for sharing your name. The Men in Black will be over soon. </p> </cfif>

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA https://www.raymondcamden.com

Comments