Acceso a recursos externos con PhoneGap/Cordova

En mi último post hablaba de las distintas técnicas que existen para hacer peticiones a otros dominios desde una página web y decía que era importante tenerlo en cuenta cuando desarrollamos una aplicación con PhoneGap/Cordova porque todas las peticiones que realicemos a servidores externos serán consideradas cross-domain.

Tras jugar un poco con Cordova e investigar un poco en internet (todavía no hay demasiada documentación sobre esto y la que hay es poco clara), lo que he visto en que en Cordova todo el acceso a recursos externos es muy dependiente de la plataforma que estemos usando (iOS, android, WP7, etc.) e incluso de la versión de la plataforma.

Hay que tener en cuenta que Cordova depende por completo de los componentes que ofrezca cada plataforma para incrustar un navegador web en una aplicación nativa. En el caso de Android es a través de un WebView, en iOS es un UIWebView, etc.

Cada plataforma permite hacer más o menos cosas desde su WebView y, aunque Cordova trata de unificar el comportamiento, digamos que todavía está la cosa un poco verde.

Lo único que tengo a mano para probar es un teléfono con android 2.3.4, así que lo que voy a contar se refiere a mis pruebas con él. Si repites las mismas pruebas con otro cacharro, puede que los resultados no sean los mismos.

OJO: Cuando hablo en este contexto de acceso a recursos externos me refiero no sólo a realizar invocaciones a servidores remotos usando AJAX, sino también a cargar páginas que estén alojadas en otro servidor.

El primer requisito para que una aplicación de Cordova en android pueda acceder a recursos remotos es solicitar el permiso de acceso a internet en el manifiesto de la aplicación:

<uses-permission android:name="android.permission.INTERNET" />

En el teléfono con el que he hecho las pruebas, que como comentaba antes lleva android 2.3.4, esto ha sido lo único que he necesitado para poder conectarme a servidores externos.

Parece ser que no siempre es tan sencillo y para esos casos no está de más conocer otra parte de Cordova que incluye en el acceso a servidores externos: la whitelist.

Cordova permite mantener una lista de sitios «permitidos» a los que sí que se puede acceder desde nuestra aplicación. La gestión de esta lista se realiza de forma diferente dependiendo de la plataforma. En el caso de android, se hace mediante el fichero res/xml/cordova.xml. En este fichero podemos añadir tantos elementos access como queramos para permitir acceso a otros dominios:

<?xml version="1.0" encoding="utf-8"?>
<cordova>
    <access origin="http://127.0.0.1*"/>
    <access origin="http://dominio-permitido.com*"/>
    <access origin="http://otro-dominio-permitido.com*" subdomains="true"/>
    <log level="DEBUG"/>
</cordova>

Existe una última alternativa, en este caso para cargar páginas desde servidores externos, que es habilitar la opción loadInWebView, lo que se salta la validación de whitelist. Para esto hace falta modificar el Activity principal:

public class MyActivity extends DroidGap {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setBooleanProperty("loadInWebView", true);
        super.loadUrl("http://dominio-externo.com/index.html");
    }
}

Conclusiones

Se nota que el desarrollo de Cordova es muy activo y está muy vivo, porque todavía hay partes de las APIs y las especificaciones que son un poco confusas o inconsistentes. Ojo que no quiero decir con esto que no sea un framework listo para usar en producción, pero hay veces que las cosas no son tan claras como nos gustaría.

8 comentarios en “Acceso a recursos externos con PhoneGap/Cordova

  1. Estimado amigo felicitarte por tan importante informacion tengo una duda, como configuraria ese archivo de manifiesto, res/xml/cordova.xml pero si lo hago desde CS6 y no con el SDK de android, y si es asi en cs6 no tengo acceso al activiti, ahora de habilitarlo a traves de una peticion ajax puedo cargar cualquier pagina web? me refiero por ejemplo http://www.google,com dentro de un div sin problema?, espero me puedas ayudar ya que soy neofito en esto de programacion mobile y desconosco hacerlo mediante java directamente y haciendolo desde cs6 se me aminora el trabajo. Gracias por la respuesta y saludos.

  2. Me temo que no tengo ni idea de CS6, pero en teoría debería dar igual qué IDE estés usando.

    Los pasos deberían ser los mismos porque al final en el .apk va metido el fichero .xml de configuración y la aplicación lo lee al arrancar.

  3. Juan Daniel Patiño dijo:

    Amigo cree un plugin para consumir un web service en phonegap el web service esta en un servidor externo pero no me funciona, yo pensaba q era el cross domain pero hice lo que tu dices y igual no funciona. Alguna idea? seria de grannn ayuda

  4. ¿Qué error te está dando? ¿Llega la petición al servidor?

    Es un poco complicado saber qué falla con la información que das.

  5. Juan Daniel Patiño dijo:

    Hola no te dije mas información por q pense q no ibas a responder jejej gracias por la molestia
    ps la verdad no se como verificar si llega la peticion aun q yo no creo, pero el mismo codigo del plugin funciona en una aplicación nativa de android. por lo q veo en el log el error es cordovaWebView timeout error cualquier ayuda sera bien recibida :)

  6. Siendo un timeout podría ser que la petición no llegue al servidor o que éste tarde mucho en responder.

    Sería interesante averiguar si llega al servidor mirando los logs de apache, iis, o lo que sea.

    De todas formas, si desde una app nativa funciona, parece que lo más probable es que no llegue, no que el servidor tarde en responder.

    Me resulta raro que te dé un error de timeout si es un tema de petición a otro servidor (sería más lógico una excepción de seguridad o algo parecido).

    Puedes probar a loggear la url a la que te estás conectando por si hubiese algún error.

  7. Juan Daniel Patiño dijo:

    La verdad no se que hacer pensé q era el cross domain pero ni idea, la única solución es aprender a programas en android y dejar de utilizar phonegap :S

  8. hola gracias uso phonegap y en proyectos anteriores y me accesaba a objetos externos de la app pero ahora compilo practicamente lo mismo y ya no me acede a nada q sea externo. alguna ayuda les agradesco phonegap me resuelve mucho y me tomo 1 año aprender como para dejar este frameware de la noche a la mañana. gracias

Comentarios cerrados.