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!
Archived Comments
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","*");
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. :)
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.
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!
The Github project CFCommunity / CFScript-Community-Components helps bridge most of the missing script functions just as another alternative.
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" />
Next time - Pastebin or Gist please. :)
@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?
I hope so. It is one of the few left.
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?
So if you hit the CFC directly, and look at headers, do you still see the CORS header (with the new one commented out)?
In other words, test by hitting the CFC in your browser w/ devtools open so you can see the headers.
Nope, nothing related to CORS come up in the headers when I hit the CFC directly
Ok, add it back, and again, hit it direct.
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.
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?
Not on this environment, it's just a plain old CFC component and nothing else :(
Then you got me. Can I hit it myself?
Wish I could let you in but this test file is sitting behind my employer's VPN. Thanks for the time nonetheless ;)
Ah... well - good luck!
You are welcome. :)