Enable CORS for ColdFusion Services

This post is more than 2 years old.

Just a quick tip. CORS is a way to allow remote JavaScript clients to use your fancy APIs. Only the best APIs support it now, but usage is growing. For a good introduction to the topic, see Brian Rinaldi's excellent blog post here: Getting HTML5 Ready - CORS. Enabling CORS may be done at the web server level, but if you don't have access to that, or if you want to specifically provide access to one particular CFC file (or method), here is how you can do it.

I've got a CFC with 2 simple methods. Don't worry about what they do - they are just samples. To allow for CORS, you can add one simple header to your code. Unfortunately, you can't do cfheader in script-based CFCs. Therefore I made a new file, head.cfm, with one line:

Obviously if you use tag-based CFCs this won't be a problem. Also note you can move that include (or the tag) into a method to enable CORS only for some methods and not others.

Hope this helps!

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for HERE Technologies. 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. You can even buy me a coffee!

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

Archived Comments

Comment 1 by Giancarlo Gomez posted on 10/19/2012 at 9:42 AM

Hello Ray,

Thanks for the tip! FYI, you can set headers in cfscript by using GetPageContext() function as follows:

GetPageContext().getResponse().addHeader("Access-Control-Allow-Origin","*");

Comment 2 by Raymond Camden posted on 10/19/2012 at 3:08 PM

I _was_ going to give a snippy response about using CF internals, then my coffee kicked in and saw you were using the _documented_ getPageContext. Good call there. :)

Comment 3 by Giancarlo Gomez posted on 10/19/2012 at 5:08 PM

LOL, I know the feeling Ray and I was hoping you wouldn't take it the wrong way, thank god for good coffee. It is a shame those functions are not well documented though, thank god they made cfdump so good! A little bit of curiosity goes far sometimes.

Comment 4 by Raymond Camden posted on 10/19/2012 at 5:18 PM

To be fair, anything under GetPageContext would be documented in the J2EE docs. _Knowing_ that though is another matter.

Actually - just checked the docs - and they are pretty good. They even mention that the methods are "mandated by the JSP specification" which is pretty clear, too!

Comment 5 by Jade Cady posted on 10/19/2012 at 6:49 PM

The Github project CFCommunity / CFScript-Community-Components helps bridge most of the missing script functions just as another alternative.

Comment 6 by Ray Varner posted on 10/30/2012 at 9:16 PM

I'll throw in a few CORS headers that may be overkill. Also, a couple of semi-related header goodies.

<!--- CORS - Cross Origin Resource Sharing --->
<cfheader name="Access-Control-Allow-Origin" value="*" />
<cfheader name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE" />
<cfheader name="Access-Control-Allow-Headers" value="Content-Type" />
<cfheader name="Content-Type" value="application/JSON; charset=utf8" />

<!--- Force cache to clear --->
<cfset headerTime=GetHttpTimeString(now()) />
<cfheader name="Cache-Control" value="must-revalidate" />
<cfheader NAME="Pragma" value="no-cache" />
<cfheader name="Expires" value="#headerTime#" />
<cfheader NAME="Last-Modified" value="#headerTime#" />

<!--- THWART Click-Jacking --->
<cfheader name="X-FRAME-OPTIONS" value="DENY" />

<!--- Force IE8 Compatibility mode --->
<cfheader name="X-UA-Compatible" value="IE=EmulateIE8" />

Comment 7 by Raymond Camden posted on 10/30/2012 at 9:18 PM

Next time - Pastebin or Gist please. :)

Comment 8 by Sean Corfield posted on 12/7/2012 at 1:31 AM

@Jade (and others), if you're using Railo, header is native in cfscript:

header name="Access-Control-Allow-Origin" value="*";

so you can put it directly into your script-based CFC.

Hopefully Adobe will add more tags to cfscript in CF11?

Comment 9 by Raymond Camden posted on 12/7/2012 at 1:38 AM

I hope so. It is one of the few left.

Comment 10 by Miguel Arvelo posted on 8/4/2016 at 6:53 PM

Raymond, dunno if you can help me out but I'm trying to enable CORS on this web service and if I add the cfheader tag as in this post I get an error about the access-control-allow-origin header being set to multiple values "*, *"

My first thought was that my dev environment must have set up CORS at the server level so I removed the cfheader tag but then I get the message about access-control-allow-origin not being set... have you encountered this before?

Comment 11 (In reply to #10) by Raymond Camden posted on 8/4/2016 at 7:16 PM

So if you hit the CFC directly, and look at headers, do you still see the CORS header (with the new one commented out)?

Comment 12 (In reply to #10) by Raymond Camden posted on 8/4/2016 at 7:16 PM

In other words, test by hitting the CFC in your browser w/ devtools open so you can see the headers.

Comment 13 (In reply to #11) by Miguel Arvelo posted on 8/4/2016 at 7:26 PM

Nope, nothing related to CORS come up in the headers when I hit the CFC directly

Comment 14 (In reply to #13) by Raymond Camden posted on 8/4/2016 at 7:27 PM

Ok, add it back, and again, hit it direct.

Comment 15 (In reply to #14) by Miguel Arvelo posted on 8/4/2016 at 8:00 PM

It shows up, yes... but when I call it from a different server I get the message

'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin '<server_address>' is therefore not allowed access.

Comment 16 (In reply to #15) by Raymond Camden posted on 8/4/2016 at 8:08 PM

That's weird then. :) You opening the the CFC directly compared to you hitting it via Ajax *should* be the same - unless you have an App.cfc sniffing the referrer and changing things. Do you?

Comment 17 (In reply to #16) by Miguel Arvelo posted on 8/4/2016 at 8:18 PM

Not on this environment, it's just a plain old CFC component and nothing else :(

Comment 18 (In reply to #17) by Raymond Camden posted on 8/4/2016 at 8:19 PM

Then you got me. Can I hit it myself?

Comment 19 (In reply to #18) by Miguel Arvelo posted on 8/4/2016 at 8:21 PM

Wish I could let you in but this test file is sitting behind my employer's VPN. Thanks for the time nonetheless ;)

Comment 20 (In reply to #19) by Raymond Camden posted on 8/4/2016 at 8:25 PM

Ah... well - good luck!

Comment 21 (In reply to #0) by Raymond Camden posted on 8/14/2017 at 7:29 PM

You are welcome. :)