以前、SitesでApex RESTクラスを公開することで認証なしで
Anonymous(サイトゲストユーザ)なREST APIをコールできます的な話をしましたが、
CORS対応できるかどうかを検証してみました!
CORSに関しては以下のURLが詳しい感じっす。
https://developer.mozilla.org/ja/docs/HTTP_access_control
http://dev.classmethod.jp/etc/about-cors/
で、今回検証したサンプル↓
@RestResource(urlMapping='/MyRestContextExample/*')
global with sharing class MyRestContextExample {
@HttpGet
global static Account doGet() {
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
res.addHeader('Access-Control-Allow-Origin', '*');
String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
return result;
}
@HttpPost
global static Boolean doPost() {
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
res.addHeader('Access-Control-Allow-Origin', '*');
return true;
}
}
実装方法としては、ResponseヘッダにAccess-Control-Allow-Originを入れてあげるだけ。
これだけで以下のようにGETリクエストとPOSTリクエストに関しては実現できます。
jQueryのAjaxでlocalhostからGET・POSTした例↓
で、問題はpreflightリクエスト(OPTIONS)が送信される場合。
preflightリクエストとは、GET・POST以外のメソッド(DELETEとかPUT)を利用したり、
カスタムヘッダ入れてたり、POSTでもContent-Typeが規定のタイプ以外(例えばapplication/json)だと、
最初にOPTIONSメソッドでオリジンやメソッドが対応しているかどうかを確認するリクエストのことです。
Apex RESTでサポートされているHTTPメソッドはGET・POST・PUT・PATCH・DELETEの5つのみなので
残念ながら、OPTIONSに対してのレスポンスを返すことができません。
ということで、AnonymousなREST APIでCORSを実現するには
GET・POSTでContent-Typeもapplication/x-www-form-urlencodedあたりでAPI設計する必要があります。
というか、そもそもSalesforceはforce.com Canvas推しな感じなので
Ajaxやるんだったら、そっちで対応するのが吉なのかもしれません。