2

I swear this was working earlier, took a break, and now its not working all of a sudden...

I'm building an AngularJS app that connects to a custom public REST api I've created with Salesforce. I've tested the REST api via curl and apigee.com and the data is being returned properly. The problem occurs when I attempt to call the same endpoint via Angulars $http.jsonp() method (which is essentially the equivalent of $.getJSON() in jQuery). When I attempt to do this the request is canceled, according to Chromes Network monitor.

I've posted this in the Salesforce board because I seem to only have this problem with apex rest api's i create with Salesforce. Are there perhaps special headers I need to send with my request? Any insight would be greatly appreciated.

Angular Factory:

angular.module('SalesforceService', [], function($provide){

    $provide.factory('$salesforce', function($http, $q){

        return {
            login: function(email, password){

                var endpoint  = 'https://merchant.dev1.cs15.force.com/freelance/services/apexrest/FreelanceService?name=Jonathan&callback=JSON_CALLBACK';
                var deferred = $q.defer();

                console.log('...calling salesforce...');
                $http.jsonp(endpoint)               
                .success(function(data){
                    console.log('--SALESFORCE RESPONSE:');
                    console.log(data);

                    deferred.resolve(data);
                }).error(function(data, status, headers, config){
                    console.log('---SALESFORCE ERROR:');
                    console.log(data);
                    console.log(status);
                    console.log(headers());
                    console.log(config);

                    deferred.reject('An error occurred when attempting to login.');
                });

                return deferred.promise;
            }
        };

    });

})

I then call this service in one of my controllers via $salesforce.login()...

Custom Salesforce REST Class:

@RestResource(urlMapping='/FreelanceService')
global class FreelanceService 
{
    global class TestObject{
        public String message;

        public TestObject(String message){
            this.message = message;
        }
    }

    @HttpGet
    global static void goGet()
    {
        String name = RestContext.request.params.get('name');

        TestObject o = new TestObject('Hello ' + name);

        RestContext.response.addHeader('Content-Type', 'application/json');
        RestContext.response.responseBody = formatResponse(o);
    }

    public static blob formatResponse(TestObject obj)
    {
        //instantiate string to be returned
        String response;

        //get callback parameter from url
        String callback = RestContext.request.params.get('callback');

        //return JSON wrapped in function if a callback parameter exists
        if(callback!=null)
        {
            response = callback + '('+JSON.serialize(obj)+')';
        }
        else
        {
            response = JSON.serialize(obj);
        }

        return blob.valueOf(response);
    }
}
  • Quick idea to help with diagnostics. Start the developer console in Salesforce, fire the request from you app, and you will be able to see the log file produced by Salesforce. There may be a clue there! e.g. Something misformatted. Has helped me out loads before. – Doug B Jun 21 '13 at 9:03
  • Hmmm... No log file was produced. Is that an indication that the request isn't even reaching the server perhaps? – jonnybro Jun 21 '13 at 9:08
  • Yeah, sounds like it. Are you using a session ID to authenticate (in which case it may have expired)? Or is your app logging in? In which case check the user details for the user it is using and scroll down to the bottom - you should see the attempted login from the app (maybe it is locked out?) – Doug B Jun 21 '13 at 9:11
  • The app is connecting to an Apex REST class that I've publicly exposed with Sites. So no authentication is necessary. I'm wondering now if there is some sort of special header I need to add to the request before sending it to SF... – jonnybro Jun 21 '13 at 9:12
  • Sorry, I'm running out of ideas now - if it's working from CURL then that suggests it is all configured correctly on the Salesforce side. Maybe check from CURL again and observe the result in Developer Console? – Doug B Jun 21 '13 at 9:17
4

Turns out because the apex service was being served from a Sandbox instead of production, Chrome was automatically canceling the request because of a certificate name mismatch error.

From the Salesforce Sites Implementation Guide:

Only production organizations have the valid secure.force.com SSL certificates to access sites using HTTPS. Note: If a site within a sandbox (non-production) organization is accessed using HTTPS, a certificate name mismatch warning may appear

  • Glad you got it sorted! That's interesting to know too. – Doug B Jun 21 '13 at 11:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.