web-dev-qa-db-fra.com

Les demandes ajax de l'application Phonegap Android vers HTTPS échouent avec le statut

Les demandes Ajax HTTPS de mon application PhoneGap/Cordova sur Android échouent inexplicablement avec le statut = 0. Il apparaît uniquement lors de la signature de l'application avec la clé de validation (c'est-à-dire, l'exportation à partir d'ADT), mais n'apparaît pas lors de la signature avec la clé de débogage (exécuté directement dans l'émulateur ou le téléphone).

request = new XMLHttpRequest()
request.open "GET", "https://some.domain/", true
request.onreadystatechange = ->
  console.log "** state = " + request.readyState
  if request.readyState is 4
      console.log "** status = " + request.status

request.send()

toujours des sorties

** state = 4
** status = 0

Peu importe si j'installe l'application depuis le Play Store ou avec l'utilitaire adb. Je présume que cela pourrait être lié au certificat, car tous les domaines HTTPS n'échouent pas de cette façon.

13
Ernests Karlsons

Cela se produit lorsque l'URL demandée répond avec un certificat erroné ou auto-signé. Lors du test ou de la distribution de l'application à des amis, la définition de <application Android:debuggable="true"...> dans AndroidManifest.xml suffit, elle contourne automatiquement les erreurs de certificat.

Mais Google Play Store n'acceptera pas un APK avec Android:debuggable="true". Tout d’abord, les certificats, bien sûr, doivent être corrigés. Mais pendant que cela se produit, voici une solution de contournement pour PhoneGap/Cordova 3:

  1. Dans votre package d'application, créez une sous-classe pour CordovaWebViewClient:

    public class SSLAcceptingCordovaWebViewClient extends CordovaWebViewClient {
        public SSLAcceptingCordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) {
            super(cordova, view);
        }
    
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();
        }
    }
    
  2. Idem pour IceCreamCordovaWebViewClient:

    public class SSLAcceptingIceCreamCordovaWebViewClient extends IceCreamCordovaWebViewClient {
        public SSLAcceptingIceCreamCordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) {
            super(cordova, view);
        }
    
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();
        }
    }
    
  3. dans <Your App Name>.Java ajouter un remplacement pour makeWebViewClient:

    @Override
    protected CordovaWebViewClient makeWebViewClient(CordovaWebView webView) {
        if(Android.os.Build.VERSION.SDK_INT < Android.os.Build.VERSION_CODES.HONEYCOMB) {
            return new SSLAcceptingCordovaWebViewClient(this, webView);
        } else {
            return new SSLAcceptingIceCreamCordovaWebViewClient(this, webView);
        }
    }
    

Et voilà! les erreurs SSL ne seront pas prises en compte. Cependant, n'utilisez jamais de certificats erronés. Essayez d'abord de les résoudre et utilisez cette solution de contournement uniquement lorsque vous êtes à court d'autres solutions.

6
Ernests Karlsons

J'avais le même problème mais ma solution était un peu différente. 

  1. Dans la seule application Android de mon application Cordova, AJAX appels à mon serveur via HTTPS étaient bloqués. Pas dans iOS, pas dans les navigateurs de bureau. Le plus déroutant, dans le navigateur Android actuel, les appels HTTPS AJAX ne fonctionneraient pas.

  2. J'ai vérifié que je pouvais passer des appels HTTPS AJAX vers des URL connues et fiables, telles que https://google.com , ainsi que des appels HTTP normaux vers toutes les URL que je voulais essayer.

  3. Cela m'a amené à penser que mon certificat SSL n'était PAS installé à 100% correctement OR le certificat bon marché (~ 10 USD) de PositveSSL n'était pas universellement approuvé OR les deux.

  4. Mon certificat a été installé sur mon AWS Load Balancer. J'ai donc cherché à comprendre comment je pouvais avoir tout gâché et à dire que PositiveSSL n'était pas le meilleur certificat à utiliser en termes de fiabilité. J'ai eu la chance de trouver un article sur l'installation de certificats par AWS ELB ET qu'ils utilisaient un certificat PositiveSSL! Ce petit bijou contient: 

"... Ne vous laissez pas berner par la boîte de dialogue AWS, la chaîne de certificats n'est pas vraiment optionnelle lorsque votre ELB parle directement à un navigateur ..."

http://www.nczonline.net/blog/2012/08/15/setting-up-ssl-on-an-Amazon-elastic-load-balancer/

Drumroll ....

J'ai réinstallé le certificat avec les informations "facultatives" sur la chaîne de certificats et voilà, les appels HTTPS AJAX sur mon serveur ont commencé à fonctionner.  

Il semble donc que la Webview Android soit plus conservatrice que le navigateur Android en termes de cert cert. Ce n'est pas totalement intuitif car ils sont censés être fondamentalement la même technologie.

13
SoldierOfFortran

L’autre option qui fonctionne également consiste à recompiler le fichier cordova.jar sous-jacent de manière à ce que le test soit complètement supprimé. Il n’ya donc aucune raison de s’inquiéter de la validité ou non de votre certificat. J'ai couru dans le problème en raison du fait qu'Android ne reconnaîtrait pas le certificat GoDaddy qui était sur le serveur. Le certificat est valide sur iOS, mais même lorsque vous naviguez depuis Android, vous vous plaignez du certificat. C'est de la branche 2.9.x car c'est ce avec quoi je travaillais.

cordova-Android/framework/src/org/Apache/cordova/CordovaWebViewClient.Java

@TargetApi(8)
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

    final String packageName = this.cordova.getActivity().getPackageName();
    final PackageManager pm = this.cordova.getActivity().getPackageManager();

    ApplicationInfo appInfo;
    try {
        appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
        handler.proceed();
        return;

        /* REMOVED TO BY PASS INVALID CERT CHAIN ****
        if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            // debug = true
            handler.proceed();
            return;
        } else {
            // debug = false
            super.onReceivedSslError(view, handler, error);
        }*/
    } catch (NameNotFoundException e) {
        // When it doubt, lock it out!
        super.onReceivedSslError(view, handler, error);
    }
}

REMARQUE: Je comprends que ce n'est pas sûr, mais lorsque tout échoue, cela résout le problème en cours depuis plus de 2 mois, y compris la réinstallation du certificat en suivant le guide d'installation de la chaîne de certificats. Peu importe si valide ou non, c'est seulement la connexion à ce serveur.

4
sneighbors

Dans mon cas, il s’agissait d’un certificat intermédiaire manquant, que j’avais dû installer sur mon serveur Web. N'oubliez surtout pas que vous utilisez des certificats bon marché. 

Vous pouvez le vérifier facilement en ligne si votre chaîne de certificats est correcte. Vous en trouverez beaucoup sur Google, par exemple. https://www.sslshopper.com/ssl-checker.html

Dans Apache2, cela fait partie de la directive VirtualHost 443, vous avez trois règles dans votre directive, cela ressemble à ça:

SSLCertificateFile    /etc/Apache2/ssl/mycert.crt

SSLCertificateKeyFile /etc/Apache2/ssl/mykey.key

SSLCertificateChainFile  /etc/Apache2/ssl/certification_auth_intermediate.crt
1
Kim Michael

Vous ne pouvez pas utiliser d'apks relese ready (phonegap) avec des certificats auto-signés. Regardez cette réponse pour obtenir plus d’informations.

lg

fastrde

0
fastr.de