Partage
  • Partager sur Facebook
  • Partager sur Twitter

FOIRE AUX QUESTIONS - ANNEXE

Contribuez

    22 mars 2010 à 19:20:52

    Exemple d'AJAX cross-domaine et sa gestion incomplète par IE 8 et 9 et Opera 10.50

    Bonjour,

    Développant dans une optique portable, je me suis aperçu qu'IE 8, IE 9 et Opera 10.50 ne semblent pas gérer complètement une équivalence de la fonction XMLHttpRequest level 2 offerte par les autres navigateurs.

    En effet, avec ces navigateurs, il est actuellement impossible de faire une requête cross-domain sécurisée depuis une page locale (entendez par-là, enregistrée n'importe où sur le poste client).


    Voici le bout de code dont je me suis inspiré:

    <script type='text/JavaScript'>
    function getXDomainRequest() {
     var xdr = null;
     
     if (window.XDomainRequest) {
      xdr = new XDomainRequest();
     } else if (window.XMLHttpRequest) {
      xdr = new XMLHttpRequest();
     } else {
      alert("Votre navigateur ne gère pas l'AJAX cross-domain !");
     }
     return xdr; 
    }
    var xdr = getXDomainRequest();
    xdr.onload = function() {
     alert(xdr.responseText);
    }
    xdr.open("GET", "http://www.foxycode.net/dev/ajax/XDomain_1.php");
    xdr.send();
    </script>
    



    Démonstration:

    1) Nous allons, tout d'abord nous assurer que ce script tourne bien en ligne. Pour ce faire, si vous avez installé Apache sur votre pc et/ou si vous disposez d'un hébergement, enregistrez ce script dans votre répertoire "www".

    Lancez-le (http://localhost/le_nom_que_vous_aurez_donné_au_script.htm) et vous verrez le bien connu Lorem ipsum dans une boîte d'alerte, sous tout navigateur récent supportant la méthode XMLHttpRequest level 2.

    2) Nous allons ensuite voir comment ça se passe en local, ouvrez cette page web par un simple double-clic ou par le menu contextuel de votre OS (de manière à ce qu'il ne soit pas ouvert par Apache) et testez sous différents navigateurs.

    Vous l'aurez remarqué, seuls IE 8, IE 9 Preview et Opera 10.50 et le supportent pas.


    Refus d'accès:

    Si l'on prête attention au gestionnaire d'erreurs d'IE 8, on peut y lire que l'accès est refusé, j'ai donc cherché les raisons d'une telle restriction.


    Les pistes:

    1) Est-ce une question de contrôle de l'accès aux sites ciblés par l'internaute avec un tel script?

    Assurément, non, puisque l'administrateur doit ajouter une fonction, côté serveur pour permettre à des scripts de type cross-domain d'y accéder.

    De plus, au moyen de cette fonction, cet administrateur peut déterminer l'origine des scripts qui peuvent ou non accéder à son contenu.

    2) Est-ce pour protéger les scripts mal sécurisés côté serveur?

    Je ne le pense pas, après tout, ce n'est pas le rôle du navigateur, cette responsabilité revient uniquement au webmaster du site concerné.


    L'intérêt de ce procédé en natif:

    - Cette technique a plusieurs avantages, une opportunité de développer de manière à mettre l'internaute à l'abri des problèmes de sécurité encourus suite à des serveurs web hackés.

    - Permettre à l'utilisateur de complètement personnaliser l'interface qu'il utilise pour communiquer avec son site préféré.

    - Économiser des ressources serveurs lors de la communication avec ses utilisateurs.


    L'appel aux développeurs:

    Sachant qu'IE 9 est en cours de création, qu'IE 8 a déjà été modifié concernant cette fonction (il peut donc l'être à nouveau) et qu'Opera n'en restera assurément pas à la version 10.50, je poste cette actualité dans l'espoir qu'elle parvienne jusqu'à leurs développeurs.


    Si vous trouvez que la résolution de ce problème peut apporter un plus au web, je vous invite à faire suivre cette news et/ou m'indiquer comment je puis me faire entendre au mieux.


    Complément d'information:

    La fonction XDomainRequest proposée par IE 8 et 9 ne supportent pas la fonction .setRequestHeader("Content-Type", "type_choisi");

    Exemple:

    <script type='text/JavaScript'>
    function getXDomainRequest() {
     var xdr = null;
     
     if (window.XDomainRequest) {
      xdr = new XDomainRequest();
     } else if (window.XMLHttpRequest) {
      xdr = new XMLHttpRequest();
     } else {
      alert("Votre navigateur ne gère pas l'AJAX cross-domain !");
     }
     return xdr; 
    }
    var xdr = getXDomainRequest();
    xdr.onload = function() {
     alert(xdr.responseText);
    }
    xdr.open("POST", "http://www.foxycode.net/dev/ajax/XDomain_1.php");
    xdr.setRequestHeader("Content-Type", "text/plain"); 
    xdr.send('');
    </script>
    


    Les requêtes POST ne semblent donc pas disponibles, tant en local qu'online...
    • Partager sur Facebook
    • Partager sur Twitter
      22 mars 2010 à 19:43:35

      Pourquoi dans la FAQ ? o_O
      T'aurais du créer un sujet...
      • Partager sur Facebook
      • Partager sur Twitter
        22 mars 2010 à 19:51:15

        Ben, parce que le but principal est d'informer...

        De plus, avec l'arrivée de Gears et de concepts tels que le mien, les problèmes cités seront, à mon avis, on risque d'en avoir besoin...

        A moins que Golmote, Restimel, toi, et bien d'autres vous dévouiez pour réécrire ces explications à la chaîne d'ici peu... ^^
        • Partager sur Facebook
        • Partager sur Twitter
          22 mars 2010 à 19:58:44

          J'écris plus à la chaîne moi.
          Je suis en train de faire ma lib avec gestion des dépendances.
          Au fait, toi qui as plein de fonctions toute faites, tu aurais pas un truc pour cloner un objet ?
          • Partager sur Facebook
          • Partager sur Twitter
            22 mars 2010 à 20:03:06

            Citation : xavierm02

            Au fait, toi qui as plein de fonctions toute faites, tu aurais pas un truc pour cloner un objet ?


            C'est une idée fixe chez toi xD
            • Partager sur Facebook
            • Partager sur Twitter
              22 mars 2010 à 20:10:47

              Des fonctions toute faites?

              Euh, j'te rappelle que j'ai que quelques mois d'xp en JS...

              Qu'entends-tu pas cloner un objet?
              • Partager sur Facebook
              • Partager sur Twitter
                22 mars 2010 à 20:19:42

                var Fred = {
                    nom: 'Fred'
                };
                var Georges = Fred;
                Georges.nom = 'Georges';
                alert(Fred.nom);//Georges
                

                Et le truc top, ça serait :
                Object.prototype.clone = function() {
                    /* code de la mort qui tue */
                };
                var Fred = {
                    nom: 'Fred'
                };
                var Georges = Fred.clone();
                Georges.nom = 'Georges';
                alert(Fred.nom);//Fred
                alert(Georges.nom);//Georges
                
                • Partager sur Facebook
                • Partager sur Twitter
                  22 mars 2010 à 20:26:42

                  A vrai dire, je n'ai jamais utilisé de "object.prototype", donc je n'en connais pas du tout son utilisation... désolé...
                  • Partager sur Facebook
                  • Partager sur Twitter
                    22 mars 2010 à 20:36:40

                    HS :
                    Arf inculte.
                    Enfin bref, mon code montre que les objets sont passés par référence.
                    Donc si tu veux pouvoir modifier une variable référençant l'objet sans modifier l'autr,e il faut le cloner.
                    Et Object, c'est le constructeur des {} et de tous les objets.
                    En gros, si tu vous quelquechose au prototype de Object, toutes les autres variables l'auront.
                    Si tu le fous au prototype de Number, tous les nombres l'auront.
                    Enfin un code explique mieux :
                    var obj = {},
                    array = [],
                    number = 0;
                    alert(obj.type);//undefined
                    alert(array.type);//undefined
                    alert(number.type);//undefined
                    Number.prototype.type = 'number';
                    alert(obj.type);//undefined
                    alert(array.type);//undefined
                    alert(number.type);//number (comme il ne trouve pas dans l'objet number [en JS, tout est objet], il va chercher dans le prototype du constructeur)
                    Object.prototype.type = 'object';
                    alert(obj.type);//object
                    alert(array.type);//object
                    alert(number.type);//number
                    Array.prototype.type = 'array';
                    alert(obj.type);//object
                    alert(array.type);//array
                    alert(number.type);//number
                    

                    Et fait, c'est sur ça que se base l'héritage en JS : les chaînes de prototype.
                    Tout hérite de Object (y compris les autres constructeurs).
                    Tous les array héritent de Array etc.
                    Ca marche pour tous les "types" de variables.

                    Et tu peux rajouter des prototypes à tes propres constructeurs :
                    function Voiture(vitesse) {
                        this.vitesse = vitesse;
                        this.position = 0;
                    }
                    var ma_307 = new Voiture('2000');
                    ma_307.avancer();//crash
                    //mais si on continue (en enlevant la ligne ci-dessus)
                    Voiture.prototype.avancer = function() {
                        this.position += this.vitesse;
                    };
                    ma_307.avancer();
                    alert(ma_307.position);//2000
                    


                    Les tutoriels en parlent pas de ça ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      22 mars 2010 à 21:46:48

                      La plupart des tutoriels puxx, ne l'oublie pas :-°

                      (Sauf le futur nôtre... OUI CA VA JE SAIS, JE VAIS M'Y METTRE ! >_< )

                      Bref... stop flooding la FAQ pliz. ;)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        22 mars 2010 à 22:12:09

                        Bon, allez, c'est pas de moi, mais j'en ai compris le principe... :)

                        <script type="text/javascript">
                        Object.prototype.clone=function(){
                        	var o=new Object();
                        	for(var property in this){
                        		o[property]=typeof(this[property])=='object'?this[property].clone():this[property];
                        	}
                        	return o;
                        }
                        </script>
                        
                        • Partager sur Facebook
                        • Partager sur Twitter
                          22 mars 2010 à 22:18:53

                          Déjà, new Object, ça ne se fait pas. Il faut utiliser la notation littérale : {}.
                          Voir tutoriel de nod_.
                          Et là, je peux te faire foirer ton truc :
                          var obj = {};
                          obj.obj = obj;
                          obj.clone();//max call stack
                          

                          Héhé :p
                          Et pas de var dans le for (qqch in obj) je crois.
                          Et typeof, c'est un opérateur, pas une fonction donc :
                          typeof this[property]
                          (enfin ta syntaxe est bonne aussi mais la mienne utilise un caractère de moins :p )

                          Et juste pour info, les array aussi, il faut les cloner parce qu'ils sont passés en référence.
                          Et les dates aussi.

                          A part ça, ton code est bien (et à peu près comme celui que j'ai fait mais qui a encore du mal avec le max call stack :p ).
                          Si ça t'intéresse, je te propose de m'envoyer un MP qu'on continue en privé :)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            22 mars 2010 à 23:00:07

                            C'est pas son code hein... il a juste googlé à ta place ;)

                            Le var dans le for/in est tout à fait correct et recommandé.

                            Et faire obj.obj = obj, c'est bas ! C'est très bas :-°
                            • Partager sur Facebook
                            • Partager sur Twitter
                              22 mars 2010 à 23:18:46

                              En effet, suis tombé là-dessus, en me disant que pour faire ce qu'il voulait, il fallait récupérer les propriétés de l'objet... mais, bon, de là à arriver à le faire moi-même, en sachant que la propriété s'appelle simplement par property... j'ai déjà fait plus compliqué... :-°

                              Le var, ici, n'est pas utile, mais par défaut, je le mets quand même, par sécurité...

                              Ton stack overflow, tu l'cherches aussi... ^^
                              mais rien ne t'empêche de limiter le nombre de propriétés, où est le problème?
                              • Partager sur Facebook
                              • Partager sur Twitter
                                22 mars 2010 à 23:51:35

                                Citation : wapper

                                en sachant que la propriété s'appelle simplement par property...



                                Hm... tu l'aurais appelé "plop", ça aurait fonctionné aussi bien ^^
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  23 mars 2010 à 0:00:26

                                  Vi, vi, j'avais bien compris... ^^
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    23 mars 2010 à 0:36:31

                                    Citation : wapper

                                    Le var, ici, n'est pas utile, mais par défaut, je le mets quand même, par sécurité...


                                    En fait si, il est très chaudement recommandé car sinon tu crées la propriété window.property, ce qui n'est pas ce que tu souhaites car cette propriété continuera à exister même après l'exécution de la boucle. Alors comme ça, ça ne semble pas dramatique mais ça peut rapidement créé des complications dont une qui s'est produite il y a peu à un de mes amis lorsqu'il codait une fonction permettant d'initialiser des requêtes AJAX de la façon suivante :

                                    function envoi() {
                                      xhr = new XMLHttpRequest();
                                      
                                      // Et tout le bordel de code permettant de réaliser une requête AJAX asynchrone.
                                    }
                                    


                                    Son problème était que certaines requêtes AJAX étaient "perdues", il ne recevait rien et ce de façon aléatoire. La raison était simple : il exécutait plusieurs fois d'affilé cette fonction, ce qui fait que les requêtes AJAX (asynchrones) n'avaient parfois pas le temps de se terminer alors que des nouvelles s'ajoutaient. Comme toutes les requêtes AJAX étaient déclarées dans la propriété window.xhr (pas de mot-clé var), cela faisait que les nouvelles requêtes remplaçaient les anciennes avant même la fin de leur exécution.

                                    </malife>

                                    Bref, n'allez JAMAIS croire que le mot-clé var est implicite en Javascript : CE N'EST PAS LE CAS !!

                                    Nes'
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      23 mars 2010 à 0:45:07

                                      Merci pour l'information, même si j'en mets toujours, dès lors que la variable en question ne doit pas impérativement être globale...
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        23 mars 2010 à 0:56:09

                                        Citation : Nesquik69

                                        <citation rid="4786964">car cette propriété continuera à exister même après l'exécution de la boucle.



                                        Nes', souviens-toi qu'en JS, les variables des boucles sont accessibles en dehors de la boucle.

                                        Mettre var permet d'éviter qu'elles soient accessible en dehors de la fonction ;)
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          23 mars 2010 à 1:02:09

                                          Citation : Golmote

                                          Citation : Nesquik69

                                          <citation rid="4786964">car cette propriété continuera à exister même après l'exécution de la boucle.



                                          Nes', souviens-toi qu'en JS, les variables des boucles sont accessibles en dehors de la boucle.


                                          WTF, je le savais même pas o_O ! Faut vraiment que je m'achète La Bible un de ces jours, je manque de ces trucs moi...
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            23 mars 2010 à 1:07:23

                                            Citation : Nesquik69

                                            WTF, je le savais même pas o_O ! Faut vraiment que je m'achète La Bible un de ces jours, je manque de ces trucs moi...



                                            Ou faire comme moi, tester plein de trucs et chercher le pourquoi du plantage... on fait parfois de bien chouettes découvertes ainsi... :)
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              23 mars 2010 à 1:42:11

                                              Chouettes ? Bof... Quand j'ai découvert, au cours de mes années de programmation, que le Javascript était un langage un peu conçu à l'arrache par endroits, j'ai été assez peu satisfait :-° .

                                              Bref, faire des découvertes par soi-même c'est bien, j'en ai fait de nombreuses et ça m'a beaucoup apporté. Cependant, on ne peut pas tout découvrir tout seul (ou presque :D !), c'est là qu'un bon bouquin s'impose.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                23 mars 2010 à 9:47:58

                                                Il faudrait en parlé dans la FAQ des protées des variables...
                                                function () {
                                                    var variable = 1;
                                                }
                                                alert(variable);//undefined
                                                for (var i=0; i<10; ++i) {
                                                    var j = i;
                                                }
                                                alert(i);//10
                                                alert(j);//9
                                                

                                                (c'est écrit sans tester mais je crois que c'est ça. à confirmer)
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  23 mars 2010 à 9:56:54

                                                  Moi je dirais i = 10 et j = 9 :-°
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    23 mars 2010 à 10:30:28

                                                    Mais le soucis c'est que Strucky va pas mettre les nouvelles idées dans la FAQ. Il s'est pas connecté depuis l'an passé :(
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      23 mars 2010 à 10:44:39

                                                      C'est quoi ce modo o_O
                                                      M'enfin du coup on peut quatter :p
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        23 mars 2010 à 11:21:42

                                                        Boarf xav, à mon avis un autre modo nous le reprochera, vu que quand on squatte, on troll, on floode ou on HS... (voire les 3 à la fois).

                                                        Donc bon, espérons plutôt qu'un autre modo prendra en charge la FAQ du JS.

                                                        (Vous pensez que je peux alerter pour demander ça ? :-° )
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          23 mars 2010 à 11:34:12

                                                          Je soutiens ta requête, Golmote... ;)
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          FOIRE AUX QUESTIONS - ANNEXE

                                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                          • Editeur
                                                          • Markdown