CORS (Cross-Origin Resource Sharing) support was added to the REST API in the Spring ’15 release. The same-origin policy restricts the browser to only making an XMLHttpRequest
to the same host that served the page. CORS allows pages to request resources from hosts other than the host that served them.
In this previous post, I described how JSONP could be used to access a public Force.com Site Apex REST method from a Site.com page. This post describes how that can be modified to be done with the new CORS security settings instead of JSONP.
The CORS settings are located in Setup > Security Controls > CORS
. Once on the CORS settings page, simply enter an URL pattern for the domain of the Force.com Site. For example, in a developer edition pre-release it could be https://mygusdeved-developer-edition.gus.force.com
or in production the custom web address www.myownsite.com
.
The REST @HttpGet
method is basically the same as it is for the JSON approach, but it no longer accepts a callback parameter and does not wrap the response in a callback, since JSONP is no longer needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@RestResource(urlMapping='/v1.0/messages') global class MessageService { @HttpGet global static void getMessages() { // buildMessages gets FeedItems List<Message> messages = buildMessages(); RestResponse res = RestContext.response; res.addHeader('Content-Type', 'application/json'); res.responseBody = Blob.valueOf( JSON.serialize(messages) ); } // buildMessages implementation... } |
The content block can remain basically the same as the JSON approach, but the dataType config property of specifying JSONP does not need to be set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script> $(document).ready(function() { $.ajax({ type: 'GET', url: '{!Site.messagesURL}', success: function(response) { var messageList = $('<ul></ul>'); $.each(response, function(idx, val) { messageList.append( '<li>' + 'Date: ' + val.messageDate + '<br />' + 'Title: ' + val.title + '<br />' + 'Body: ' + val.body + '<br />' + '</li>' ); }); $('#messages').html(messageList); } }); }); </script> |
Once published, the page can be seen in action by navigating to the URL, e.g., https://mygusdeved-developer-edition.gus.force.com/s/, https://www.myownsite.com/myPage, etc. One drawback is that it does not work in the Site.com Studio editor, because the requesting URL is sitepreview.force.com and not the published Site’s URL.
All code is available in this gist.
Hii Peter,
I found your article while I was searching for a way to take advantage of this new feature. What I am trying to do is to call my Rest api method (which is a public force.com site) from my localhost asp.net app. However it looks it doesn’t work or I am missing something. I added my localhost address where my website is hosted to CORS list in my org but I never get Access-Control-Allow-Origin in the response. It works only if I manually add in the apex code:
res.addHeader(‘Access-Control-Allow-Origin’, ‘http://localhost:30374’);
which would be totally fine if I don’t need to use POST with application/json header in which case CORS causes browser first to fire “Options” request which then results in “method not allowed” error from Salesforce. Salesforce doesn’t support annotations like ‘@HttpOptions’
Do you have any idea if my scenario is supposed to work at all or I am missing the limits of this new feature?
Thank you!
Here is the article that carries answer on my question: https://developer.salesforce.com/blogs/developer-relations/2015/01/spring-15-preview-cors-force-com-rest-api.html
It explicitly says following:
“here are a couple of limitations in the Spring ’15 CORS implementation:
Apex REST Methods are not accessible via CORS.”
Knowing that and failing to do what I wrote in my previous comment I actually doubt that this example in this post actually works in reality.
Looks like this new feature in Spring 15 works on different domains only for built in Salesforce rest api.
More update on this one. It is confirmed by SF that it is an issue. CORS in Spring 15 doesn’t work for query and sobjects services. It is scheduled for next(summer 15) release to be fixed
https://success.salesforce.com/issues_view?id=a1p300000008Xe0AAE