Consumir Un Webservice Desde Angularjs

Consumir un webservice desde Angularjs

Últimamente estoy dando muchas vueltas con AngularJs. El desarrollo tiene que ir encaminado hacia la creación de aplicaciones web que se comporten de igual manera ya sea si la estas viendo desde un móvil, una tableta o un ordenador. El dispositivo debe ser un elemento totalmente independiente de la experiencia de usuario de una web o una aplicación, por eso en los últimos tiempos han salido varios frameworks que nos ayudan a hacer aplicaciones webs colocando una capa de abstracción entre las particularidades de cada plataforma y el usuario.

Pues bien, como ya algunos sabrán, estoy tonteando mucho últimamente con frameworks de desarrollo de aplicaciones para móviles. Hay muchos en el mercado pero yo he decidido empezar por Ionic, que es un framework lanzado por Twitter y basado en Apache Cordova y AngularJs y del que ya hablé en un artículo anterior.

Lo que tiene en común el desarrollo con este tipo de frameworks es que en algún momento si o si vas a necesitar hacer una llamada a un webservice para consumir unos datos, ya sea mediante una api RESTful o mediane SOAP y aquí es dónde viene el problema con el que me he encontrado estos días, cómo consumir un webservice que devuelve un conjunto de datos en JSON desde AngularJS.

En uno de los controladores de mi aplicación AngularJS, tenía una llamada asíncrona que utilizaba JSONP para comunicarse. Esta técnica de comunicación está pensada para suplir las limitaciones de AJAX en las comunicaciones asíncronas, permitiéndonos hacer peticiones a páginas que se encuentren en otros dominios diferentes sin que nos salten errores de CORS.

¿Y qué son las CORS? Pues quiere decir Cross-Origin Resource Sharing, o en la lengua de Cervantes, Sistema de Compartir Recursos entre Dominios Cruzados y es una política de seguridad del W3C que básicamente consiste en la permisividad de poder acceder a recursos de un dominio desde otro dominio diferente. Esta política nos viene genial para las aplicaciones que vamos a empaquetar con Cordova, pero no solo para apps nos ayuda sino que cada vez es más frecuente diseñar páginas/aplicaciones que beban de diferentes fuentes de datos.

El problema que nos encontrarnos al tener que utilizar esta política de seguridad es que si no la configuramos y utilizamos correctamente estamos dejando una puerta abierta para ataques maliciosos. Alguien con muy malas ideas podría acceder a todos los recursos del servidor mediante un servicio expuesto si no hemos definidos bien las CORS. Que puedan acceder a una imagen que tenemos alojada en nuestro servidor pues a lo mejor nos da un poco igual, pero ya no nos dará tan igual si acceden a las cookies de sesión o realizan ataques CSRF en nuestra web/aplicación…

Pues lo dicho, para consumir un webservice desde AngularJs, tendremos que hacer uso en nuestro navegador del objeto $http. Como dice la fuente original:

The $http service is a core Angular service that facilitates communication with the remote HTTP servers via the browser’s XMLHttpRequest object or via JSONP.

 var dataJSONP = $http({
         method: 'JSONP', 
         url: 'https://example.org/webservice'
});

Lo que hay al otro lado de la url es un webservice que devuelve unos datos en formato JSON. Podría ser algo tan sencillo como:

 $data = array( 'date' => '22/11/2015',
        'title' => 'Título para un post chorra',
   );
 echo json_encode($data); 

Definimos un array y lo devolvemos codificándolo mediante la función json_encode, fin. Sin embargo si ejecutamos esto recibiremos un error como el siguiente:

Cross-Origin Resource Sharing

Cross-Origin Resource Sharing

Para solucionarlo, tendremos que añadir lo siguiente a la respuesta de nuesto webservice:

 header('content-type: application/jsonp; charset=utf-8');
 header('Access-Control-Allow-Headers: Content-Type');
 header('Access-Control-Allow-Methods: GET, POST');
 header('Access-Control-Allow-Origin: *');
 echo 'angular.callbacks._0('.json_encode($arr).')'; 
  • content-type: application/jsonp; charset=utf-8: indicamos el tipo de respuesta y su codificación.
  • Access-Control-Allow-Headers: Content-Type: indicamos que cabeceras HTTP usar al hacer la petición.
  • Access-Control-Allow-Methods: GET, POST: métodos permitidos para hacer la petición.
  • Access-Control-Allow-Origin: indicamos los origenes de la petición permitidos.
  • angular.callbacks._0: JSONP requiere encapsulemos la respuesta en una función de callback de Javascript.

Con esto conseguiremos que nuestra aplicación AngularJs pueda consultar datos desde fuentes externas.

He encontrado una respuesta muy buena en Stackoverflow sobre el uso de angular.callbacks en las respuestas JSONP. Si quieres leerla ayudame a que el artículo se difunda compartiéndolo por las redes sociales.

Gorka Muñoz Andrés

Me llamo Gorka Muñoz y soy un desarrollador melómano. Combino a la perfección la búsqueda de nuevos grupos con la pasión por la tecnología. Desde chiquitito me ha gustado la programación, ahora que soy mayor estoy metido en el mundo del SEO sin olvidarme del /Dev.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *