Consultar un servicio remoto con el proxy web en SharePoint

Normalmente, al compilar Complementos de SharePoint, se deben incorporar datos de diversos orígenes. Por razones de seguridad, existen mecanismos de bloqueo que impiden la comunicación entre dominios. Al usar el proxy web, las páginas web del complemento pueden acceder a los datos del dominio remoto y del dominio de SharePoint.

Como desarrollador, puede usar el proxy web que se expone en las API de cliente, como los modelos de objeto de cliente de .NET y de JavaScript. Al usar el proxy web, la solicitud inicial se emite en SharePoint. A su vez, SharePoint solicita los datos al punto de conexión especificado y envía la respuesta a la página.

Use el proxy web cuando quiera que la comunicación se produzca en el nivel de servidor. Para obtener más información, vea Acceso a datos seguro y modelos de objetos de cliente para complementos de SharePoint.

El proxy web de SharePoint es el intermediario entre su código y el origen de datos externo

Símbolos de

Requisitos previos para usar los ejemplos de este artículo

Para seguir los pasos de este ejemplo, necesita lo siguiente:

Conceptos básicos que necesita conocer antes de usar el proxy web

En la tabla siguiente se muestran algunos artículos útiles que le permitirán comprender los conceptos propios de un escenario entre dominios de complementos de SharePoint.

Título del artículo Descripción
Complementos de SharePoint Obtenga información sobre el nuevo modelo de complementos de SharePoint, que permite crear complementos (pequeñas soluciones fáciles de usar para usuarios finales).
Acceso a datos seguro y modelos de objetos de cliente para complementos de SharePoint Obtenga información sobre las opciones de acceso a datos de Complementos de SharePoint. Este artículo proporciona instrucciones sobre las alternativas de alto nivel que tiene que elegir al trabajar con datos en el complemento.
Hospedar webs, webs de complemento y componentes de SharePoint en SharePoint Aprenda cuál es la diferencia entre una web de host y una web de complemento. Descubra qué componentes de SharePoint se pueden incluir en una Complemento de SharePoint, qué componentes se implementan en la web de host, qué componentes se implementan en la web de complemento y cómo se implementa la web de complemento en un dominio aislado.
Seguridad entre dominios del lado cliente Explore amenazas entre dominios y casos de uso, principios de seguridad para solicitudes de origen cruzado y valore los riesgos que tiene para los desarrolladores mejorar el acceso entre dominios desde aplicaciones web que se ejecutan en el explorador.

Ejemplo de código: acceso a datos en un servicio remoto con el proxy web

Para leer datos desde un servicio remoto, siga este procedimiento:

  1. Cree un proyecto de complemento de SharePoint.

  2. Modificar la página Default.aspx para que use el proxy web al consultar el servicio remoto.

  3. Modifique el manifiesto de complemento para permitir la comunicación con el dominio remoto.

En la ilustración siguiente se muestra la ventana del explorador con datos del servicio remoto en una página web de SharePoint.

Página web de SharePoint con datos del servicio remoto

Página de SharePoint con datos del servicio remoto

Para crear el proyecto de complemento de SharePoint

  1. Abra 2015 como administrador. (Para ello, haga clic con el botón derecho en el icono de 2015 del menú Inicio y seleccione Ejecutar como administrador).

  2. Cree un proyecto con la plantilla Complemento de SharePoint.

    En la ilustración siguiente se muestra la ubicación de la plantilla Complemento de SharePoint de 2015 (Plantillas>Visual C#>Office/SharePoint>Complementos de Office).

    Plantilla de Visual Studio Complemento de SharePoint

    Plantilla de Visual Studio Complemento de SharePoint


  3. Especifique la dirección URL del sitio web de SharePoint que quiera usar para la depuración.

  4. Seleccione Hospedado en SharePoint como la opción de hospedaje del complemento.

Para modificar la página Default.aspx y hacer que use el proxy web con el modelo de objetos de JavaScript

  1. Haga doble clic en la página Default.aspx, en la carpeta Páginas.

  2. Copie el siguiente marcado y péguelo en la etiqueta de contenido PlaceHolderMain de la página. El marcado hace las siguientes tareas:

    • Proporciona un marcador de posición para los datos remotos.

    • Hace referencia a los archivos de JavaScript de SharePoint.

    • Prepara la solicitud con un objeto WebRequestInfo.

    • Prepara el encabezado Accept de la solicitud para especificar la respuesta en el formato Notación de objetos de JavaScript (JSON).

    • Emite una llamada al punto de conexión remoto.

    • Controla la finalización correcta y representa los datos remotos en la página web de SharePoint.

    • Controla los errores, procesando los mensajes de error en la página web de SharePoint.

    Categories from the Northwind database exposed as an OData service: 
    
    <!-- Placeholder for the remote content -->
    <span id="categories"></span>
    
    <!-- Add references to the JavaScript libraries. -->
    <script 
        type="text/javascript" 
        src="../_layouts/15/SP.Runtime.js">
    </script>
    <script 
        type="text/javascript" 
        src="../_layouts/15/SP.js">
    </script>
    <script type="text/javascript">
    (function () {
        "use strict";
    
        // Prepare the request to an OData source
        // using the GET verb.
        var context = SP.ClientContext.get_current();
        var request = new SP.WebRequestInfo();
        request.set_url(
            "http://services.odata.org/Northwind/Northwind.svc/Categories"
            );
        request.set_method("GET");
    
        // We need the response formatted as JSON.
        request.set_headers({ "Accept": "application/json;odata=verbose" });
        var response = SP.WebProxy.invoke(context, request);
    
        // Let users know that there is some
        // processing going on.
        document.getElementById("categories").innerHTML =
                    "<P>Loading categories...</P>";
    
        // Set the event handlers and invoke the request.
        context.executeQueryAsync(successHandler, errorHandler);
    
        // Event handler for the success event.
        // Get the totalResults node in the response.
        // Render the value in the placeholder.
        function successHandler() {
    
            // Check for status code == 200
            // Some other status codes, such as 302 redirect
            // do not trigger the errorHandler. 
            if (response.get_statusCode() == 200) {
                var categories;
                var output;
    
                // Load the OData source from the response.
                categories = JSON.parse(response.get_body());
    
                // Extract the CategoryName and Description
                // from each result in the response.
                // Build the output as a list.
                output = "<UL>";
                for (var i = 0; i < categories.d.results.length; i++) {
                    var categoryName;
                    var description;
                    categoryName = categories.d.results[i].CategoryName;
                    description = categories.d.results[i].Description;
                    output += "<LI>" + categoryName + ":&amp;nbsp;" +
                        description + "</LI>";
                }
                output += "</UL>";
    
                document.getElementById("categories").innerHTML = output;
            }
            else {
                var errordesc;
    
                errordesc = "<P>Status code: " +
                    response.get_statusCode() + "<br/>";
                errordesc += response.get_body();
                document.getElementById("categories").innerHTML = errordesc;
            }
        }
    
        // Event handler for the error event.
        // Render the response body in the placeholder.
        // The body includes the error message.
        function errorHandler() {
            document.getElementById("categories").innerHTML =
                response.get_body();
        }
    })();
    </script>
    

(Opcional) Para modificar la página Default.aspx y que use el proxy web con el extremo de REST

  1. Haga doble clic en la página Default.aspx, en la carpeta Páginas.

  2. Copie el siguiente marcado y péguelo en la etiqueta de contenido PlaceHolderMain de la página. El marcado hace las siguientes tareas:

    • Proporciona un marcador de posición para los datos remotos.

    • Hace referencia a la biblioteca jQuery.

    • Prepara la solicitud que se enviará al extremo SP.WebRequest.Invoke.

    • Prepara el cuerpo de una solicitud con un objeto SP.WebrequestInfo. El objeto incluye el encabezado Accept para especificar la respuesta en el formato Notación de objetos de JavaScript (JSON).

    • Emite una llamada al punto de conexión remoto.

    • Controla la finalización correcta y representa los datos remotos en la página web de SharePoint.

    • Controla los errores y representa los mensajes de error en la página web de SharePoint.

    Categories from the Northwind database exposed as an OData service: 
    
    <!-- Placeholder for the remote content -->
    <span id="categories"></span>
    
    <script 
        type="text/javascript" 
        src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.min.js">
    </script>
    
    <script type="text/javascript">
    (function () {
        "use strict";
    
        // The Northwind categories endpoint.
        var url =
            "http://services.odata.org/Northwind/Northwind.svc/Categories";
    
        // Let users know that there is some
        // processing going on.
        document.getElementById("categories").innerHTML =
                    "<P>Loading categories...</P>";
    
        // Issue a POST request to the SP.WebProxy.Invoke endpoint.
        // The body has the information to issue a GET request
        // to the Northwind service.
        $.ajax({
            url: "../_api/SP.WebProxy.invoke",
            type: "POST",
            data: JSON.stringify(
                {
                    "requestInfo": {
                        "__metadata": { "type": "SP.WebRequestInfo" },
                        "Url": url,
                        "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.
        // Get the totalResults node in the response.
        // Render the value in the placeholder.
        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;
                var output;
    
                // Load the OData source from the response.
                categories = JSON.parse(data.d.Invoke.Body);
    
                // Extract the CategoryName and Description
                // from each result in the response.
                // Build the output as a list
                output = "<UL>";
                for (var i = 0; i < categories.d.results.length; i++) {
                    var categoryName;
                    var description;
                    categoryName = categories.d.results[i].CategoryName;
                    description = categories.d.results[i].Description;
                    output += "<LI>" + categoryName + ":&amp;nbsp;" +
                        description + "</LI>";
                }
                output += "</UL>";
    
                document.getElementById("categories").innerHTML = output;
            }
            else {
                var errordesc;
    
                errordesc = "<P>Status code: " +
                    data.d.Invoke.StatusCode + "<br/>";
                errordesc += response.get_body();
                document.getElementById("categories").innerHTML = errordesc;
            }
        }
    
        // Event handler for the error event.
        // Render the response body in the placeholder.
        // The 2nd argument includes the error message.
        function errorHandler() {
            document.getElementById("categories").innerHTML =
                arguments[2];
        }
    })();
    </script>
    
    

Para editar el archivo de manifiesto del complemento

  1. En el Explorador de soluciones, abra el menú contextual del archivo AppManifest.xml y seleccione Ver código.

  2. Copie la siguiente definición de RemoteEndPoints como elemento secundario del nodo App.

    <RemoteEndpoints>
        <RemoteEndpoint Url=" http://services.odata.org" />
    </RemoteEndpoints>
    

El elemento RemoteEndpoint se usa para especificar el dominio remoto. El proxy web valida que las solicitudes enviadas a dominios remotos se declaren en el manifiesto del complemento. Puede crear hasta 20 entradas en el elemento RemoteEndpoints. Solo se tiene en cuenta la parte de la entidad emisora: http://domain:port y http://domain:port/website se consideran el mismo extremo. Puede emitir llamadas a muchos extremos diferentes dentro del mismo dominio con una sola definición RemoteEndpoint.

Para crear y ejecutar la solución

  1. Seleccione la tecla F5.

    Nota:

    Al seleccionar F5, Visual Studio compila la solución, implementa el complemento y abre la página de permisos del complemento.

  2. Seleccione el botón Confiar.

  3. Seleccione el icono del complemento en la página Contenidos del sitio.

    En la ilustración siguiente se muestran los datos remotos en la página web de SharePoint.

    Datos remotos en la página web de SharePoint

    Página de SharePoint con datos del servicio remoto

Solución de problemas

Problema Solución
Visual Studio no abre el explorador después de seleccionar la tecla F5. Establezca el proyecto de complemento de SharePoint como proyecto de inicio.
Excepción no controlada no se ha definido SP. Asegúrese de que tiene acceso al archivo SP.RequestExecutor.js en una ventana del explorador. Si usa el servidor local como entorno de desarrollo, debe desactivar la comprobación de bucle invertido de IIS.

Ejecute el siguiente comando desde un símbolo del sistema de Windows PowerShell: New-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa -Name "DisableLoopbackCheck" -value "1" -PropertyType dword

Precaución: no se recomienda deshabilitar la comprobación de bucle invertido de IIS en un entorno de producción.
El tamaño de la respuesta del punto de conexión remoto supera el límite configurado. El tamaño de la respuesta de las solicitudes del proxy web no debe superar los 200 KB.
No se admite la combinación de esquema y puerto. La combinación de esquema y puerto de llamada necesita cumplir los criterios siguientes:

Esquema - Puerto
http - 80
https - 443
http o https - 7000-10000

Importante: Los puertos de salida están sujetos a la disponibilidad del firewall del host. En concreto, en SharePoint Online solo están disponibles los puertos http-80 y https-443.

Ver también