left-icon

SharePoint 2013 App Model Succinctly®
by Fabio Franzini

Previous
Chapter

of
A
A
A

CHAPTER 9

Cross-Domain and Remote Service Calls

Cross-Domain and Remote Service Calls


When we develop client-side code, we have limitations on making calls to domains different from that of our app. This is because browser security prevents cross-domain communication.

With app development for SharePoint, in reality, we find ourselves in front of two different cases: SharePoint calls that refer, for example, to different sites or HostWeb than the app, and calls to services outside SharePoint.

In both cases, we must submit to safety rules and cannot make calls to the SharePoint site if we don't have access to those sites. This also means we cannot call external resources if the app is not authorized to do so.

Cross-domain calls

In this case, to access the REST API and work with different sites from the app web, we should use the JavaScript cross-domain library (see more below):

var executor = new SP.RequestExecutor(appweburl);

var request = {

    URL: appweburl

         + "/_api/SP.AppContextSite(@target)/web/lists?@target='"

         + hostweburl + "'",

    method: "GET",

    headers: { "Accept": "application/json; odata=verbose" },

    success: function () {

        // Success code.

    },

    error: function () {

        // Error code.

    }

}

executor.executeAsync();

This example uses JavaScript to make a REST call that returns the list of lists within the SharePoint HostWeb using the cross-domain library found in SP.RequestExecutor.js (I will explain this later).

This library uses a proxy page that is hosted in an Iframe on a page of the app to enable cross-domain communication.

When the app page and SharePoint website are in different security zones, the authorization cookie cannot be sent.

If there are no authorization cookies, the library cannot load the proxy page and we cannot communicate with SharePoint.

Remote Services Calls

To construct applications, it may be useful to make calls to remote services that are perhaps not hosted by SharePoint to find information that the app needs or to send data that may be processed outside of the app itself.

For the cross-domain issues mentioned above, we are forced to use a JavaScript library that allows us to make calls outside of SharePoint or to use a web proxy that the CSOM JavaScript provides us.

For this web proxy, before actually calling to indicate it, we need check to see if the remote endpoint that we are trying to rely on is present within the file AppManifest.xls. If SharePoint will call for us, we will then return the result; otherwise, an exception will be thrown.

Let‘s look at an example implemented in JavaScript on how to implement this type of call.

First of all, recall that there are referencing JavaScript libraries in the CSOM that offer the web proxy feature:

<script type="text/javascript"

        src="/_layouts/15/sp.runtime.js"></script>

<script type="text/javascript"
        src="/_layouts/15/sp.js"></script>

Now implement the code to make the call. The following example makes a call to the OData service that exposes data from the sample Northwind database at:
http://services.odata.org/Northwind/Northwind.svc:

"use strict";

var serviceUrl = "http://services.odata.org/Northwind/Northwind.svc/Categories";

var contex t = SP.ClientContext.get_current();

// Creating an instance of the SP.WebRequestInfo

// for calling the WebProxy for SharePoint.

var request = new SP.WebRequestInfo();

// Set the URL.

request.set_url(serviceUrl);

// Set the HTTP Method.

request.set_method("GET");

// Set response format.

request.set_headers({ "Accept": "application/json;odata=verbose" });

// Make command to invoke.

var response = SP.WebProxy.invoke(context, request);

// Invoke the request.

context.executeQueryAsync(successHandler, errorHandler);

// Event handler for the success event.

function successHandler() {

    if (response.get_statusCode() == 200) {

        // Load the OData source from the response.

        var categories = JSON.parse(response.get_body());

        // Extract the CategoryName and description.

        for (var i = 0; i < categories.d.results.length; i++) {

            var categoryName = categories.d.results[i].CategoryName;

            var description = categories.d.results[i].Description;

            // Make some operation on data.

            // ***************************

        }

    }

    else {

        var errorMessage = "Status Code: " +

                           response.get_statusCode() +

                           "Message: " + response.get_body();

        alert(errorMessage);

    }

}

// Event handler for the error event.

function errorHandler() {

    var errorMessage = response.get_body();

    alert(errorMessage);

}

As we can see, the WebRequestInfo object is a bridge to make the call. On this subject we set the URL, the HTTP Method, and any HTTP Headers. Then, through the ClientContext we will make the call that will return the requested data to the service.

If we want to make the same call but use only a REST call, without using the CSOM, we can do so in the following way:

"use strict";

var serviceUrl = "http://services.odata.org/Northwind/Northwind.svc/Categories";

// Make a POST request to the SP.WebProxy.Invoke endpoint.

$.ajax({

    URL: "/_api/SP.WebProxy.invoke",

    type: "POST",

    data: JSON.stringify(

        {

            "requestInfo": {

                "__metadata": { "type": "SP.WebRequestInfo" },

                "Url": serviceUrl,

                "Method": "GET",

                "Headers": {

                    "results": [{

                        "__metadata": { "type": "SP.KeyValue" },

                        "Key": "Accept",

                        "Value": "application/json;odata=verbose",

                        "ValueType": "Edm.String"

                    }]

                }

            }

        }),

    headers: {

        "Accept": "application/json;odata=verbose",

        "Content-Type": "application/json;odata=verbose",

        "X-RequestDigest": $("#__REQUESTDIGEST").val()

    },

    success: successHandler,

    error: errorHandler

});

// Event handler for the success event.

function successHandler(data) {

    // Check for status code == 200

    // Some other status codes, such as 302 redirect,

    // do not trigger the errorHandler.

    if (data.d.Invoke.StatusCode == 200) {

        var categories = JSON.parse(data.d.Invoke.Body);

        // Extract the CategoryName and Description

        for (var i = 0; i < categories.d.results.length; i++) {

            var categoryName = categories.d.results[i].CategoryName;

            var description = categories.d.results[i].Description;

            // Make some operation on data

            // ***************************

        }

    }

    else {

        alert("Error!");

    }

}

// Event handler for the success event.

function errorHandler() {

    alert("Error!");

}

In this case, we see how a call is made using the jQuery AJAX method, passing a series of parameters required to inform the REST service _api that you're trying to make a call to a remote endpoint.

You have the choice to use the CSOM or REST mode to make a call to a remote endpoint.

Summary

In this chapter, we learned about the problems of cross-domain communication that exist in SharePoint, and we have learned how to work around them using the capabilities that are provided by CSOM and the REST API.

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.