Cómo conectar a un servidor HTTP mediante Windows.Web.Http (HTML)

[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows en tiempo de ejecución. Si estás desarrollando para Windows 10, consulta la documentación más reciente

Envía una solicitud GET a un servicio web y recupera la respuesta mediante la clase Windows.Web.Http.HttpClient del espacio de nombres Windows.Web.Http.

[Obtén la muestra de HTTPClient ahora.]

Las clases del espacio de nombres Windows.Web.Http proporcionan una interfaz de programación para aplicaciones de cliente HTTP modernas. El espacio de nombres Windows.Web.Http y los espacios de nombres relacionados Windows.Web.Http.Headers y Windows.Web.Http.Filters proporcionan componentes de cliente HTTP que permiten a los usuarios realizar solicitudes HTTP y recibir respuestas HTTP de servicios web modernos a través de HTTP.

Windows 8.1 presenta Windows.Web.Http, el espacio de nombres de Windows en tiempo de ejecución que se usa para las aplicaciones de Windows que se conectan a servicios web HTTP y REST. Esta nueva API proporciona compatibilidad con todas las características en todos los lenguajes admitidos y reemplaza la API de HTTP original de Windows 8.

Esta nueva API reemplaza el uso de las tres API distintas con diversas características que antes eran necesarias para cada proyección de lenguaje en Windows 8.

En las operaciones de solicitud básicas, la nueva API tiene una interfaz sencilla para administrar la tareas más comunes y proporciona valores predeterminados razonables para autenticación (AUTH) que se aplican a la mayoría de los escenarios. En las operaciones HTTP más complejas, se ofrecen funcionalidades adicionales como las siguientes:

  • Métodos para verbos comunes (DELETE, GET, PUT y POST)

  • Compatibilidad con diseños y configuraciones de autenticación comunes

  • Acceso a detalles de la Capa de sockets seguros (SSL) en el transporte

  • Capacidad de incluir filtros personalizados en aplicaciones avanzadas

  • Capacidad de obtener, establecer y eliminar cookies

  • Información de progreso de solicitudes HTTP disponible en métodos asincrónicos

La clase Windows.Web.Http.HttpClient se usa para enviar y recibir solicitudes básicas a través de HTTP. Proporciona la clase principal para enviar solicitudes HTTP y recibir respuestas HTTP de un recurso identificado mediante un URI. Esta clase se puede usar para enviar una solicitud GET, PUT, POST, DELETE y otras a un servicio web. Cada una de estas solicitudes se envía como una operación asincrónica.

La clase Windows.Web.Http.HttpRequestMessage representa un mensaje de solicitud HTTP enviado por Windows.Web.Http.HttpClient. La clase Windows.Web.Http.HttpResponseMessage representa un mensaje de respuesta HTTP recibido de una solicitud HTTP. El IETF define los mensajes HTTP en la especificación RFC 2616.

El espacio de nombres Windows.Web.Http proporciona varias clases distintas que representan contenido HTTP (el cuerpo de entidad HTTP y los encabezados de contenido con cookies) asociado a una solicitud HTTP o una respuesta HTTP. Estas clases distintas permiten que el contenido use un búfer, una secuencia y datos nombre-valor codificados con el tipo MIME application/x-www-form-urlencoded, el tipo MIME multipart/* y el tipo MIME multipart/form-data. También puede definirse contenido personalizado.

En este ejemplo, la clase HttpStringContent se usa para representar la respuesta HTTP como una cadena.

El espacio de nombres Windows.Web.Http.Headers admite la creación de cookies y encabezados HTTP, que se asocian como propiedades a objetos HttpRequestMessage y HttpResponseMessage.

Requisitos previos

Los siguientes ejemplos de este tema se proporcionan en JavaScript y HTML. Es necesario un conocimiento básico de las solicitudes HTTP tal y como se detallan en la especificación RFC 2616.

También es posible realizar solicitudes HTTP en una aplicación con JavaScript y HTML mediante WinJS.xhr y XMLHttpRequest. Para obtener más información, consulta Conexión a un servicio web (aplicaciones de Windows en tiempo de ejecución con JavaScript y HTML).

Instrucciones

Paso 1: Crear un nuevo proyecto

  1. Abre Microsoft Visual Studio 2013 y selecciona Nuevo proyecto en el menú Archivo.
  2. En la lista de plantillas, elige JavaScript.
  3. En la sección, elige Store apps.
  4. En la sección, selecciona Universal Apps, Windows apps, o Windows Phone apps (en función de la plataforma de destino) y, luego, selecciona Aplicación vacía.
  5. Asigna el nombre HttpClientGet a la aplicación y haz clic en Aceptar.

Paso 2: Establecer las funcionalidades para habilitar el acceso de red

Debes establecer las funcionalidades de red para tu aplicación para habilitar el acceso a una red privada doméstica o de trabajo, y a Internet. Para esta aplicación, tendrías que habilitar las funcionalidades de red porque el cliente se va a conectar a servicios web.

Para una aplicación que usa Windows.Web.Http.HttpClient para conectarse a un servicio web en un equipo diferente, la aplicación necesitaría tener establecidas las funciones de red. Si la aplicación necesita poder conectarse como cliente a servicios web en Internet, se necesita la función Internet (cliente). Si la aplicación necesita poder conectarse como cliente a servicios web en una red doméstica o de trabajo, se necesita la función Redes privadas (cliente y servidor).

Nota  En Windows Phone, solo hay una funcionalidad de red, Internet (cliente y servidor), que habilita todo el acceso a redes para la aplicación.

 

Si el servicio web se ejecuta en el mismo equipo que la aplicación, se necesita acceso de bucle invertido. Las aplicaciones que se desarrollen y se ejecuten en Visual Studio 2013 se registrarán automáticamente como exentas de las restricciones de bucle invertido. Para obtener más información, consulta Cómo habilitar el aislamiento de red de bucle invertido y de depuración.

Si quieres obtener información más detallada acerca del acceso de red, consulta Cómo configurar las funcionalidades de red.

Estos pasos son necesarios para establecer las funcionalidades de red de una aplicación antes de que se implemente y si la aplicación accede a un servicio web en Internet o en una red privada o de trabajo.

  1. Abre el archivo package.appxmanifest con Visual Studio 2013.

  2. Selecciona la pestaña Funcionalidad.

  3. Para compilar la versión para Windows de la muestra, selecciona las funcionalidades Internet (cliente) y Redes privadas (cliente y servidor).

    Para compilar la versión para Windows Phone de la muestra, selecciona la funcionalidad Internet (cliente y servidor).

  4. Guarda y cierra el archivo de manifiesto.

Paso 3: Agregar interfaz de usuario HTML

  • En esta sección, definimos el diseño de la aplicación en HTML para especificar el tamaño y la posición aproximados de cada objeto en la aplicación. Completamos la interfaz de usuario de la aplicación agregando controles y contenido para mostrar los datos.

    En este ejemplo se usan elementos de interfaz de usuario HTML sencillos que incluyen lo siguiente:

    • Un control con una class que se usa para una etiqueta de texto y el campo de entrada de la dirección URI de entrada y un button que se usa para iniciar la solicitud sincrónica.

    • Un control con una class con una etiqueta de texto y un campo de texto para mostrar el estado actual. Aquí es donde se mostrarán los mensajes de estado y de error. Este control también contiene una class donde se muestra la salida recibida del servicio web. En este ejemplo, el resultado de la operación HTTP GET se muestra como texto sin formato que contiene formato HTML.

    Abre la carpeta js y abre el archivo default.js existente y agrega los siguientes elementos de interfaz de usuario a este archivo.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>HttpClientGet</title>
    
        <!-- WinJS references - Windows -->
        <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
    
        <!-- WinJS references - Phone -->
        <link href="/css/ui-themed.css" rel="stylesheet" />
        <script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
        <script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>
    
        <!-- HttpClientGet references -->
        <link href="/css/default.css" rel="stylesheet" />
        <script src="/js/default.js"></script>
        <script src="/js/mainpage.js"></script>
    </head>
    
    <body>
        <div data-win-control="SampleInput">
            <p> Download the contents of a page and display it. </p>
            <p class="clear">
                <label for="inputAddress">URI Address:</label>
                <input type="text" id="inputAddress" value="https://www.contoso.com" />
            </p>
            <p>
                <button id="startButton">Start</button>
            </p>
        </div>
        <div data-win-control="SampleOutput">
            <p class="clear">
                <label for="statusText">Status:</label>
                <input type="text" id="statusText" value="" />
            </p>
            <textarea id="outputView"></textarea>
        </div>
    </body>
    </html>
    

Paso 4: Crear el HttpClient

  • Crea primero el objeto Windows.Web.Http.HttpClient y agrega un encabezado de agente de usuario.

    De manera predeterminada, el objeto HttpClient no envía ningún encabezado de agente de usuario con la solicitud HTTP al servicio web. Algunos servidores HTTP, incluidos algunos servidores web de Microsoft, requieren que se incluya un encabezado de agente de usuario con la solicitud HTTP enviada desde el cliente. El servidor HTTP devuelve un error si no hay ningún encabezado. Es necesario agregar un encabezado de agente de usuario mediante las clases en el espacio de nombres Windows.Web.Http.Headers. Para evitar estos errores, agregamos este encabezado a la propiedad HttpClient.DefaultRequestHeaders.

    Abre la carpeta js, agrega un nuevo archivo mainpage.js y agrega el siguiente código al archivo.

    (function () {
        "use strict";
    
        var httpClient;
        var httpPromise;
    
        var page = WinJS.UI.Pages.define("/html/mainpage.html", {
            ready: function (element, options) {
                document.getElementById("startButton").addEventListener("click", start, false);
    
                httpClient = new Windows.Web.Http.HttpClient();
    
                // Add a user-agent header
                headers = httpClient.defaultRequestHeaders;
    
                // UserAgent is a HttpProductInfoHeaderValueCollection
                // A collection of HttpProductInfoHeaderValue items
    
                // The safe way to check a header value from the user is the TryParseAdd method
                // Since we know this header is okay, we use ParseAdd with will throw an exception
                // with a bad value 
    
                headers.userAgent.parseAdd("ie");
                headers.userAgent.parseAdd("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
            }
        });
    })();
    

    Abre la carpeta js y el archivo default.js y agrega el siguiente código al archivo.

    (// For an introduction to the Blank template, see the following documentation:
    // https://go.microsoft.com/fwlink/p/?LinkID=232509
    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    startButton.onclick = start;
    
                } else {
                    startButton.onclick = start;
                }
                args.setPromise(WinJS.UI.processAll());
            }
        };
    
        app.oncheckpoint = function (args) {
            // This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
        app.start();
    })();
    

Paso 5: Enviar la solicitud GET y recibir la respuesta

  • Cuando se hace clic en el botón Inicio, primero validamos que el URI especificado en inputAddress sea válido. Luego enviamos la solicitud GET con el URI y esperamos la respuesta del servidor HTTP.

    La mayoría del trabajo ya está hecho en el controlador de clics del Button Inicio. Al hacer clic en este botón, se actualiza el texto de los elementos de interfaz de usuario statusText y outputView. Primero comprobamos la dirección URI de entrada para asegurarnos de que el usuario ha pasado una dirección URI válida. Si tenemos un URI válido del usuario, la aplicación envía la solicitud HTTP GET al URI especificado y espera la respuesta HTTP. Si se produce un error o una excepción, el resultado se muestra en el elemento de interfaz de usuario statusText. Si no se produce ningún error, la respuesta del servicio web se muestra en el elemento de interfaz de usuario outputView.

    Se inicia una excepción cuando se pasa una cadena no válida para el identificador uniforme de recursos (URI) al constructor del objeto Windows.Foundation.Uri.

    En JavaScript, no hay ningún método para probar y analizar una cadena en un URI. Para capturar esta excepción en ese caso, usa un bloque try/catch en el código donde se crea el URI.

    En este ejemplo también se comprueba que el esquema HTTP del URI es HTTP o HTTPS, ya que son los únicos esquemas admitidos por Windows.Web.Http.HttpClient.

    Si usas las palabras clave then y done en JavaScript, el código para enviar la solicitud GET y recuperar la respuesta de forma asincrónica es similar al código que usarías para completar esta operación de forma sincrónica.

    Las excepciones a causa de errores en la red (pérdida de la conectividad, errores de conexión y errores del servidor HTTP, por ejemplo) pueden producirse en cualquier momento. Estos errores hacen que se arrojen excepciones. Si tu aplicación no las controla, las excepciones pueden ocasionar que el tiempo de ejecución finalice la aplicación. Debes escribir código para controlar las excepciones cuando llamas a la mayoría de los métodos de red asincrónicos. Algunas veces, cuando se produce una excepción, se puede reintentar un método de red para intentar solucionar el problema. Otras veces, la aplicación podría necesitar un plan para continuar sin conectividad de red usando los datos almacenados anteriormente en caché. Para obtener más información sobre cómo controlar las excepciones de red, consulta Controlar excepciones en aplicaciones de red.

    El método HttpResponse.EnsureSuccessStatusCode inicia una excepción si el servidor web devuelve un código de estado de error HTTP HttpResponse.StatusCode que no se encuentre en el intervalo Successful (200-299) de la solicitud. Si se produce un error, usamos un bloque try/catch para las excepciones e imprimimos el mensaje de la excepción en el elemento de interfaz de usuario statusText.

    La propiedad HttpResponse.Content representa el contenido de la respuesta HTTP. El método HttpClient.GetAsync(Uri) lee el contenido HTTP en una cadena como una operación asincrónica. Reemplazamos las etiquetas <br> del texto HTML devuelto por nuevas líneas para facilitar la presentación. Si el método se ejecuta correctamente, mostramos el HttpResponse.StatusCode en el elemento de interfaz de usuario statusText y el HttpResponse.Content devuelto por el servicio web en el elemento de interfaz de usuario outputView.

    Abre la carpeta js y agrega el siguiente código al archivo mainpage.js.

        function start()
        {
    
            var response = new Windows.Web.Http.HttpResponseMessage();
    
            var statusText = document.getElementById("statusText");
            var outputView = document.getElementById("outputView");
    
            // The value of 'inputAddress' is set by the user 
            // and is therefore untrusted input. 
            // If we can't create a valid absolute URI, 
            // We notify the user about the incorrect input.
    
            statusText.Text = "Testing URI is valid.";
    
            var uriString = document.getElementById("inputAddress").value.trim();
            if (!uriString) {
                return;
            }
    
            var resourceUri;
            try {
               resourceUri = new Windows.Foundation.Uri(uriString);
            }
            catch (Exception) {
                statusText.Text = "Invalid URI, please re-enter a valid URI.";
                return;
            }
    
            if (resourceUri.schemeName != "http" && resourceUri.schemeName != "https") {
                statusText.Text = "Only 'http' and 'https' schemes supported. Please re-enter URI";
                return;
            }
    
            var responseBodyAsText="";
            outputView.Text = "";
            statusText.Text = "Waiting for response ...";
    
            httpPromise = httpClient.getAsync(resourceUri).then(function (response) {
                outputStatus = response.statusCode + " " + response.reasonPhrase;
    
                response.EnsureSuccessStatusCode();
    
                response.content.readAsStringAsync().then(function (responseBodyAsText) {
                // Format the HTTP response to display better
                responseBodyAsText = responseBodyAsText.replace(/<br>/g, "\r\n");
                outputView.value = responseBodyAsText;
                return response;
            });
        )};
    
        httpPromise.done(function (response) {
            statusText.value = response.StatusCode + " " + response.ReasonPhrase + "\r\n";
        }, onError);
    
        function onError(error) {
            statusText.value = "Error = " + error.number + "  Message: " + error.message;
        }
    
    })();
    

    Windows.Web.Http.HttpClient usa WinInet para enviar solicitudes HTTP y de servicios web y recibir respuestas. El valor de tiempo de espera predeterminado que usa WinInet en una operación de conexión HTTP es 60 segundos. Si un servidor HTTP o servicio web está temporalmente inactivo o bloqueado por un firewall y el servidor no responde o no puede responder a la solicitud Windows.Web.Http.HttpClient, WinInet espera los 60 segundos predeterminados antes de devolver un error que provoca el inicio de una excepción en la aplicación. Si la consulta del nombre de un servidor HTTP devuelve varias direcciones IP para el nombre, WinInet prueba otras direcciones IP para el sitio, cada una de ellas con un tiempo de espera predeterminado de 60 segundos antes de producir un error. Una aplicación que realiza una solicitud HTTP o servicio web podría esperar varios minutos reintentando diversas direcciones IP antes de que WinInet devolviera un error y se iniciara una excepción. El usuario podría percibir este comportamiento como si la aplicación hubiera dejado de funcionar. El tiempo de espera predeterminado que usa WinInet para enviar y recibir después de que se haya establecido una conexión es 30 segundos.

    Para que la aplicación responda mejor y se minimicen estos problemas, se podría mejorar la aplicación estableciendo un tiempo de espera menor en las operaciones de Windows.Web.Http.HttpClient para que las operaciones dieran error antes por el tiempo de espera y no por la configuración predeterminada de WinInet. Para obtener más información sobre cómo configurar un tiempo de espera, consulta Establecer valores de tiempo de espera con WinJS.xhr o HttpClient y Cómo establecer tiempos de espera en operaciones de socket.

Observaciones

En este tema hemos revisado cómo usar la clase Windows.Web.Http.HttpClient para enviar una solicitud GET a un servicio web y recuperar la respuesta con Windows.Web.Http.HttpResponseMessage y las clases relacionadas en el espacio de nombres Windows.Web.Http.Headers.

Temas relacionados

Otros recursos

Conexión a servicios web

Controlar excepciones en aplicaciones de red

Cómo configurar las funcionalidades de red

Cómo habilitar el bucle invertido y depurar el aislamiento de red

Establecer valores de tiempo de espera con WinJS.xhr o HttpClient

Referencia

Windows.Foundation.Uri

Windows.Web.Http

Windows.Web.Http.Filters

Windows.Web.Http.Headers

Muestras

Muestra de HttpClient

Muestra de autenticación web