web-dev-qa-db-fra.com

window.name en tant que transport de données: une approche valable?

Vue d'ensemble et question originale

window.name est une bête intéressante. La description de MDN suggère l'intention initiale:

Le nom de la fenêtre est utilisé principalement pour définir des cibles pour les hyperliens et les formulaires. Windows n'a pas besoin de noms.

Cela signifie donc que nous pouvons ouvrir la console dans cette fenêtre et écrire:

var win = window.open('http://google.com', 'el goog');

... et laissez-le passer par le bloqueur de popups, cela devrait ouvrir google.com dans une fenêtre nommée "el goog". Je ne peux pas accéder à la propriété name de win en raison de la règle de même origine, mais si j'ouvre une console dans la nouvelle fenêtre et saisis name, j'obtiendra "el goog".

Si je renvoie la fenêtre au domaine depuis lequel je l'ai ouverte (dans ce cas, stackoverflow.com), je peux obtenir la propriété name et elle n'a pas changé.

win.location.replace(location.href);
win.name; // "el goog"

Cela signifie que nous pouvons avoir une sorte de magasin de sessions inter-domaines en définissant la propriété name d'une fenêtre.

Si google.com avait changé la valeur de window.name avant que la fenêtre ne soit renvoyée au domaine d'origine, nous verrions la nouvelle valeur au lieu de "el goog". Cela pourrait être utilisé comme transport de données entre domaines, similaire à JSONP ou CORS.

J'ai fait quelques recherches pour essayer de trouver plus d'informations, et apparemment, le dojo pense que c'est légitime en tant que transport. D'une certaine manière, cela ne me rassure pas complètement. Ma question est donc la suivante: des sites réputés utilisent-ils window.name comme moyen de transport de données? Je pense que cela pourrait être facilement repéré, car leurs documents disent quelque chose comme "ajouter 'callback" à la chaîne de requête pour JSONP, ou ajouter "quel que soit" pour window.name, "mais je ne l'ai jamais vu quelque chose comme ça. Quelqu'un a-t-il réellement remarqué cela dans la nature?


Question alternative

Il se peut que personne n’utilise réellement cette technique; si c'est vrai, alors (comme l'a souligné Rob W), la question ci-dessus est sans réponse. Alors, ma deuxième question est: quels sont les problèmes avec cette approche? Cela pourrait aider à expliquer pourquoi il n'a pas vraiment été adopté.

À mon avis, cette approche présente au moins deux avantages par rapport à JSONP.

  • Avec JSONP, vous faites confiance à un script d'une origine étrangère pour s'exécuter sur votre domaine. Avec window.name, tous les scripts inclus par un site malveillant s’exécuteraient sur leur propre domaine.

  • Avec JSONP, il n'y a aucun moyen de transmettre des données volumineuses (quelque chose de trop volumineux pour une URL), ni de créer un HTTP POST. Avec window.name, nous pouvons publier des données arbitraires de toute taille.

Quels sont les inconvénients?


Exemple de mise en oeuvre

Voici un exemple très simple d'implémentation client. Cela ne gère pas les demandes POST, seulement GET.

function fetchData(url, callback) {
    var frame = document.createElement('iframe');
    frame.onload = function() {
        frame.onload = function() {
            callback(frame.contentWindow.name);
            frame.parentNode.removeChild(frame);
        }
        frame.src = 'about:blank';
    }
    frame.src = url;
    document.body.appendChild(frame);
}

// using it

fetchData('http://somehost.com/api?foo=bar', function(response) {

    console.log(response);

});​

J'ai mis en place un violon pour le tester ici . Il utilise ce script comme serveur de test. 

Voici un exemple un peu plus long qui peut faire des requêtes POST: http://jsfiddle.net/n9Wnx/2/


Résumé

Autant que je sache, window.name n'a pas été retenu comme moyen de transport de données. Je me demande si ma perception est exacte (donc la question initiale) et si oui, je me demande pourquoi c'est le cas. J'ai énuméré quelques avantages que window.name semble avoir par rapport à JSONP. Quelqu'un peut-il identifier quelques inconvénients qui auraient pu contribuer à empêcher l'adoption de cette technique?

Plus précisément, quelqu'un peut-il me donner une raison solide de ne pas utiliser winow.name comme moyen de transport de données? 

43
Dagg Nabbit

window.name n'est pas particulièrement efficace comme moyen de transport, car (autant que je sache), il ne déclenche aucun événement lorsqu'il est modifié. Par conséquent, une application qui tentait d'utiliser window.name comme canal de communication bidirectionnel devrait l'interroger à la recherche de mises à jour.

En ce qui concerne les sites qui l'utilisent réellement: je n'en ai jamais entendu parler. Il y en a peut-être, mais je n'ai entendu parler de cette technique que dans un sens purement théorique.

6
duskwuff

Plus précisément, quelqu'un peut-il me donner une raison solide de ne pas utiliser winow.name comme moyen de transport de données? 

Bien que window.name puisse être un véritable sauveur en matière de transport de données lors de changements de domaine, il ne peut pas être utilisé comme mécanisme de transport de données universel et réel en raison de l'absence d'une API permettant de stocker et de récupérer des données. Par exemple, localStorage fournit setItem, getItem. Une telle API est nécessaire pour résumer la manière dont les valeurs sont réellement stockées et pour éviter les conflits de format (ce qui se produirait si différentes bibliothèques exécutées de votre côté stockaient dans des formats différents).

Pour autant que je sache, window.name n'a pas été retenu comme moyen de transport de données. Je me demande si ma perception est exacte (d'où la question initiale) et si oui, je me demande pourquoi c'est le cas. 

Étant donné que window.name ne fournit pas une telle couche de stockage/récupération - comme décrit dans la remarque ci-dessus - les bibliothèques tierces ne peuvent pas savoir quel format utiliser pour stocker des données dans window.main et n'utilisera donc jamais window.main car ce n'est pas fiable. Si vous (c’est-à-dire votre programme principal) étiez le seul à lire ou écrire à window.name, vous pourriez décider de stocker les données au format JSON et de stocker/récupérer en conséquence. Mais que se passerait-il si une bibliothèque tierce souhaitait également stocker/récupérer quelque chose et si elle décidait de ne pas utiliser json mais d'utiliser un autre des nombreux formats de sérialisation ... cela casserait accidentellement votre format json et causerait définitivement des ennuis .

0
B12Toaster