I'm new to rest services in Salesforce. I've defined the following rest service in Apex:
@RestResource(urlMapping='/mediaPlanDetail')
global with sharing class MediaPlanDetailService {
@HttpGet
global static String doGet() {
RestResponse response = RestContext.response;
response.addHeader('Access-Control-Allow-Origin', '*');
response.addHeader('content-Type', 'application/json');
String URL = 'http://services.somecompany.com/services/loadByMediaPlanId';
String payloadStr = '';
System.debug(RestContext.request.requestBody);
String rows = RestContext.request.params.get('rows'); System.debug('rows = ' + rows);
String page = RestContext.request.params.get('page'); System.debug('page = ' + page);
String sidx = RestContext.request.params.get('sidx'); System.debug('sidx = ' + sidx);
String sord = RestContext.request.params.get('sord'); System.debug('sord = ' + sord);
String mediaPlanId = RestContext.request.params.get('mediaPlanId');
String pageSize = RestContext.request.params.get('pageSize');
String finalUrl = URL +
'?rows=' + rows +
'&page=' + page +
'&sidx=' + sidx +
'&sord=' + sord +
'&mediaPlanId=' + mediaPlanId +
'&pageSize=' + pageSize +
''
;
Http objhttp = new Http();
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
req.setMethod('GET');
req.setEndpoint(finalUrl);
req.setHeader('Accept','application/json');
req.setHeader('Content-type','application/json; charset=UTF-8');
req.setHeader('Accept-Language', 'en-US');
req.setTimeout(120000);
try {
res = objhttp.send(req);
if(res.getStatus().equalsIgnoreCase('OK') && res.getStatusCode() == 200) {
// Logic to parse the response
String body = res.getBody();
system.debug('-------- HttpResponse received: ' + body);
final String PAYLOAD_ELEMENT = '\"payload\":';
final String EXCEPTION_ELEMENT = '\"exception\":';
integer payloadPos = body.indexOf(PAYLOAD_ELEMENT); System.debug('payloadPos = ' + payloadPos);
integer exceptionPos = body.indexOf(EXCEPTION_ELEMENT); System.debug('exceptionPos = ' + exceptionPos);
payloadStr = body.substring(payloadPos + PAYLOAD_ELEMENT.length(), exceptionPos - 1);
}
}
catch(System.CalloutException e) {
System.debug('Callout error: '+ e);
}
return payloadStr;
}
}
I'm calling this service using a jQuery plugin call jqGrid. Here's a snippet of the code:
$(document).ready(function () {
var mpId = $.urlParam('mediaPlanId');
$("#jqGrid").jqGrid({
url: '/services/apexrest/mediaPlanDetail', // this fails with 302 Found
//url: 'https://somecompany--cpq.cs7.my.salesforce.com/services/apexrest/mediaPlanDetail', // this fails with 401 not authorized
postData: {
mediaPlanId: mpId,
pageSize: 10
},
loadBeforeSend: function(jqXHR) {
//jqXHR.setRequestHeader("Authorization", 'OAuth ' + __sfdcSessionId);
jqXHR.setRequestHeader("Authorization", 'Bearer {!$Api.Session_ID}');
//jqXHR.setRequestHeader("Authorization", 'OAuth {!$Api.Session_ID}');
},
The VF page where I'm calling the service has this location:
https://somecompany--cpq--c.cs7.visual.force.com/apex/jqgrid_test_page?mediaPlanId=2271
When I call the service using
/services/apexrest/mediaPlanDetail
the service returns a 302 with an alternative Location in the header:
https://somecompany--cpq.cs7.my.salesforce.com/services/apexrest/mediaPlanDetail?mediaPlanId=2271&pageSize
=10&_search=false&nd=1437743215834&rows=10&page=1&sidx=&sord=asc
When I use the redirected location as the URL, I get a 401 Unauthorized response with Cross-Origin Request Blocked messages in my browser.
In either case, my Apex rest service is never called. I see nothing in the Debug Logs indicating that my browser is actually calling it.
This looks like a classic cross domain scripting issue between the Salesforce VP page domain and the domain used for Apex rest services. I spent a lot of time yesterday reading various posts on both calling SF rest services and cross domain issues, but wasn't able to find a solution. Can anyone help me with this?