Search code examples
javascriptsharepointazurexmlhttprequestcsom

No 'Access-Control-Allow-Origin' header


I have an MVC application deployed to Azure which was created as a SharePoint App Part (Provider-Hosted) for a SharePoint Online site. All Client ID and Secret ID are set correctly within SharePoint site and the Azure web Application.

The App does spin up from the SharePoint site but the JSOM logic is throwing a No 'Access-Control-Allow-Origin' header exception when it runs this simple JS logic...

<script type="text/javascript">
    var hostweburl;

    // Load the required SharePoint libraries.
    $(document).ready(function () {

        // Get the URI decoded URLs.
        hostweburl =
            decodeURIComponent(
                getQueryStringParameter("SPHostUrl")
        );

        // The js files are in a URL in the form:
        // web_url/_layouts/15/resource_file
        var scriptbase = hostweburl + "/_layouts/15/";

        // Load the js files and continue to
        // the execOperation function.
        $.getScript(scriptbase + "SP.Runtime.js",
            function () {
                $.getScript(scriptbase + "SP.js", execOperation);
            }
        );
    });

    // Function to execute basic operations.
    function execOperation() {

        // Continue your program flow here.
        hostweburl =
           decodeURIComponent(
               getQueryStringParameter("SPHostUrl")
       );
        retrieveWebSite(hostweburl);

    }

    // Function to retrieve a query string value.
    // For production purposes you may want to use
    // a library to handle the query string.
    function getQueryStringParameter(paramToRetrieve) {
        var params =
            document.URL.split("?")[1].split("&");
        var strParams = "";
        for (var i = 0; i < params.length; i = i + 1) {
            var singleParam = params[i].split("=");
            if (singleParam[0] == paramToRetrieve)
                return singleParam[1];
        }
    }


    function retrieveWebSite(siteUrl) {
        var clientContext = new SP.ClientContext(siteUrl);
        this.oWebsite = clientContext.get_web();

        clientContext.load(this.oWebsite);

        clientContext.executeQueryAsync(
            Function.createDelegate(this, this.onQuerySucceeded),
            Function.createDelegate(this, this.onQueryFailed)
        );
    }

    function onQuerySucceeded(sender, args) {
        alert('Title: ' + this.oWebsite.get_title() +
            ' Description: ' + this.oWebsite.get_description());
    }

    function onQueryFailed(sender, args) {
        alert('Request failed. ' + args.get_message() +
            '\n' + args.get_stackTrace());
    }

</script>

The exception occurs in the function retrieveWebSite when it attempts to obtain the Client Context for the site...

        var clientContext = new SP.ClientContext(siteUrl);

The exception is as follows ...

XMLHttpRequest cannot load https://mySharePointSiteName.sharepoint.com/sites/Apps/_api/contextinfo. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://myWebSiteName.azurewebsites.net' is therefore not allowed access.

I thought the whole IFrames stuff takes care of this?


Solution

  • You need to use the SP.RequestExecutor like so:

    http://blogs.msdn.com/b/officeapps/archive/2012/11/29/solving-cross-domain-problems-in-apps-for-sharepoint.aspx

    -Edit

    Not sure anyone uses this method anymore but here's a new link:

    https://learn.microsoft.com/en-us/archive/blogs/officeapps/solving-cross-domain-problems-in-apps-for-sharepoint

    and here's the sample snip from the blog:

     // Load the cross-domain library. 
    $(document).ready(function () { 
      var hostweburl; 
      var appweburl; 
      
      //Get the URI decoded URLs. 
      hostweburl = decodeURIComponent( getQueryStringParameter("SPHostUrl") ); 
      appweburl = decodeURIComponent( getQueryStringParameter("SPAppWebUrl") ); 
      
      // Load the .js files using jQuery's getScript function. 
      $.getScript(
        hostweburl + "/_layouts/15/SP.RequestExecutor.js",
        continueExecution
      );
      
      // After the cross-domain library is loaded, execution 
      // continues to this function. 
      function continueExecution() { 
        var executor; 
        
        // Initialize your RequestExecutor object. 
        executor = new SP.RequestExecutor(appweburl); 
        // You can issue requests here using the executeAsync method 
        // of the RequestExecutor object.
      } 
      
      // Function to retrieve a query string value.  
      function getQueryStringParameter(paramToRetrieve) {
        var params = document.URL.split("?")[1].split("&");
        var strParams = "";
    
        for (var i = 0; i < params.length; i = i + 1) {
          var singleParam = params[i].split("=");
          if (singleParam[0] == paramToRetrieve)
            return singleParam[1];
        }
      }
    });
    

    Have a great day!