AJAX to Sugar REST blocked by CORS

I tried sending an AJAX request with jQuery to a SugarCRM REST endpoint, but it was blocked by Cross Origin Resource Sharing and returned HTTP 404 along with an error.

This is the AJAX request:

$.ajax({
        type: 'POST',
        url: 'https://example.sugarinstance.com/rest/v10/Cases/web/submit',
        data: jsonData,
        dataType: 'json',
        contentType: 'application/json',
        success: function(response) {
          console.log('SUCCESS')
          console.log(response)
        }
      })

And this is the error returned:

XMLHttpRequest cannot load https://example.sugarinstance.com/rest/v10/Cases/web/submit. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 404.

This is the endpoint I created just to test without authentication since it was not working at all:

<?php

class Web2CaseApi extends SugarApi
{
    public function registerApiRest()
    {
        return array(
            'Web2CaseEndpoint' => array(
                'reqType' => 'POST',
                'noLoginRequired' => true,
                'path' => array('Cases', 'web', 'submit'),
                'method' => 'newCase',
                'shortHelp' => 'Receives JSON data for a new Case record',
            ),
        );
    }
    public function newCase($api, $args)
    {
        return $args;
    }
}

This endpoint now appears in the API help, so it definitely exists.

How am I supposed to use AJAX to send data to SugarCRM if it is blocked?
Should the server be set to allow CORS by default?

I also tried these options in the jQuery AJAX request to no avail:

crossDomain: true,
headers: {
  'Access-Control-Allow-Origin': '*'
},
  • Hi Artis, 

    In the following discussion this topic was discussed and resolved;

    How do you enable cross origin resource sharing (CORS) for Sugar 7 REST API? 

    Does this apply to your usecase?

    Thanks,

    Dennis

  • I found out that CORS can be used by keeping the request to a bare minimum and adding a couple headers in the API endpoint file.
    The request should have no headers, just data, url and method.
    These two lines should be at the top of the custom API endpoint file (I put them above the class definition):

    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST');

    Note that the origin URL should be specified as narrowly as possible when making the endpoint public so that random people on the internet cannot take the code and keep using it on their website. Unless that's exactly what you want, of course.

  • Finally discovered (from stackoverflow) out how to send Cross Domain Request to Sugar API with the custom header oauth-token included

    In .htaccess, add these settings

    Enable the following CORS headers on the server.  Note: The wildcard for Access-Control-Allow-Origin is for development only. 

    <IfModule mod_headers.c>
          Header always set Access-Control-Allow-Origin "*"
          Header always set Access-Control-Allow-Methods "POST, GET"
          Header always set Access-Control-Allow-Headers "oauth-token"
    </IfModule>

    Use mod_rewrite to handle the OPTIONS by just sending back a 204 OK with those headers.  

    <IfModule mod_rewrite.c>

          RewriteEngine On

          RewriteCond %{REQUEST_METHOD} OPTIONS
          RewriteRule ^(.*)$ $1 [R=204,L]

    </IfModule>

    Longer explanation at https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/

  • This is happening because of the CORS 3 (Cross Origin Resource Sharing) . For every HTTP request to a domain, the browser attaches any HTTP cookies associated with that domain. This is especially useful for authentication, and setting sessions. You are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request.

    JSONP ( JSON with Padding ) is a method commonly used to bypass the cross-domain policies in web browsers. You’re on domain example.com, and you want to make a request to domain example.nett . To do so, you need to cross domain boundaries. JSONP is really a simple trick to overcome the XMLHttpRequest same domain policy. So, instead of using XMLHttpRequest we have to use < script > HTML tags, the ones you usually use to load JavaScript files , in order for JavaScript to get data from another domain.

    Localhost

    If you need to enable CORS on the server in case of localhost, you need to have the following on request header.

    Access-Control-Allow-Origin: http://localhost:9999

    Also, this kind of trouble is now partially solved simply by using the following jQuery instruction:

    <script>
    $.support.cors = true;
    </script>