JQuery .ajax échoue lorsque le nom d’utilisateur d’authentification de base a le symbole @ (ios / cordova)

J’ai une application phonegap avec jQuery 1.9.1 qui fonctionnait très bien tant que le nom d’utilisateur ne contenait pas le symbole “@” (comme dans les adresses électroniques). Il n’échoue que sur iOS.

Je soupçonne que ce n’est probablement pas le code @ ou quelque chose du genre.

  • iPhone , il ne frappe jamais aucun rappel (terminé, échec ou toujours), Wireshark montre que la demande n’arrive pas au serveur .
  • Chrome Desktop : fonctionne bien.
  • Android , fonctionne bien.

    $.ajax({ url: "https://" + this.hostname + "/alertusmw/services/rest/" + endPoint, type: method, dataType: 'json', contentType: 'application/com.alertus-v1.0+json', cache:false, username: this.username, password: this.password, beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Basic " + $.base64.encode(this.username + ":" + this.password)); }, data: options.data }).done(function(response) { console.log("DONE: " + method + ' completed: '); console.log(response); options.success( response ); }) .fail(function(jqXHR, textStatus, errorThrown) { console.log("FAIL: " + method + " FAILED: " + textStatus + "\n" + "ERROR THROWN: " + errorThrown); console.log("jqXHR thing: ", jqXHR); options.error(jqXHR,textStatus,errorThrown); }) .always(function(jqXHR, textStatus, errorThrown) { console.log("In the always", jqXHR, textStatus, errorThrown); }); 
    • Vérifié, l’en-tête base64 est identique sur les ordinateurs de bureau iphone et chrome.
    • Ce n’est pas un problème de certificate SSL.
    • Ce n’est pas un problème cors
    • Ce n’est pas un utilisateur / passe invalide

Encore une fois, fonctionne parfaitement si le nom d’utilisateur n’a pas de «@»

La raison pour laquelle je soupçonne quelque chose d’encodé en url, c’est que si le navigateur l’a posté comme https://user@domain:[email protected] : https://user@domain:[email protected] , le navigateur n’inclurait probablement pas la partie domain:password tant qu’hôte ( le premier @ est ce qui sépare l’utilisateur: passe du domaine …

Voici ce qui m’a appris à cela:

entrez la description de l'image ici

^ – Je pensais que l’intérêt de l’encodage en base64 était précisément d’éviter les problèmes de caractères spéciaux … alors j’ai pensé que c’était peut-être utile en chrome …

Related SO Posts: – L’authentification de base échoue dans cordova ios (pas de réponse, légèrement différent)

Je parierais que le problème n’utilise pas un contentType : "application/x-www-form-urlencoded" .

Quoi qu’il en soit, vous devez absolument déboguer votre vue Web sur un périphérique réel, afin de rechercher les erreurs XHR sur la console Safari. Si vous n’êtes pas familier avec le débogage à distance Safari, rien de plus simple:

  • Dans votre iPhone / iPad, accédez à Paramètres -> Safari -> Avancé => Activer Web Inspector.
  • connectez-vous à MacOSX via un câble et sélectionnez votre application dans le menu “Développer” de Safari sur votre bureau.
  • Maintenant, vérifiez toutes les erreurs concernant votre demande, ou mieux encore, déboguez le code et les rappels étape par étape.

Essayez d’encapsuler encodeURIComponent () avant l’encodage Base64.

 beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Basic " + $.base64.encode(encodeURIComponent(this.username + ":" + this.password))); }, 

Lorsque le texte codé en base64 n’est pas codé de l’autre côté, il ressemble toujours (comme vous l’avez dit) à user@domain:[email protected] [email protected].

 var getAuthToken = function (user, pass) { var token = ""; if (user) { token = token + encodeURIComponent(user); } if (pass) { token = token + ":" + encodeURIComponent(pass); } token = $.base64.encode(token); return "Basic " + token; }; 

Puis changez légèrement votre code:

 xhr.setRequestHeader("Authorization", getAuthToken(this.username, this.password));