Comment deux instances d'un utilisateur peuvent-elles communiquer entre les images?

Reportez-vous à la technique d'avoir le même JavaScript pour s'exécuter à la fois dans une page Web et un iframe, comme décrit dans cette réponse :

Par exemple, supposons que vous ayez cette page sur domain_A.com:

<html> <body> <iframe src="http://domain_B.com/SomePage.htm"></iframe> </body> </html> 

Si vous définissez vos directives @match comme ceci:

 // @match http://domain_A.com/* // @match http://domain_B.com/* 

Ensuite, votre script sera exécuté deux fois – une fois sur la page principale et une fois sur l'iframe comme s'il s'agissait d'une page autonome.

Quelles sont les options pour que les deux instances du script puissent communiquer entre elles?

Cela serait nécessaire pour synchroniser les instances. Par exemple, demandez à iframe script-instance d'exécuter sa tâche uniquement après l'achèvement de l'instance de script de la page Web, et vice versa.

Les deux instances de script peuvent communiquer entre elles en utilisant postMessage() . En ce qui concerne:

Cela serait nécessaire pour synchroniser les instances, par exemple pour que l'iframe puisse exécuter sa tâche uniquement après la fin de la page Web et vice versa.

C'est exactement ce qui est montré dans cette réponse incroyablement brillante . 😉
Mais Chrome a des bugs dans la façon dont il présente des frames / iframes à des extensions (Et les utilisateurs de Chrome sont des extensions avec un manifeste généré automatiquement).
Donc, pour contourner ces bugs, vous devez injecter le code qui appelle postMessage() .

Le script suivant montre comment. Il:

  • Fonctionne à la fois dans un iframe et la page contenant.
  • Gère les iframes de domaine croisé.
  • Il démontre le contrôle inter-script ayant la logique suivante:
    1. La page conteneur se configure pour écouter les messages de l'iframe.
    2. L'iframe s'arrête pour écouter les messages de la page conteneur.
    3. L'iframe envoie le premier message à la page conteneur.
    4. Lorsque la page conteneur reçoit ce message, il renvoie un autre message à l'iframe.

Installez ce script:

 // ==UserScript== // @name _Cross iframe, cross-domain, interscript communication // @include http://fiddle.jshell.net/9aQv5/* // @include http://www.puppylinux.com/ // ==/UserScript== console.log ("Script start..."); if (window.top === window.self) { console.log ("Userscript is in the MAIN page."); //--- Setup to process messages from the GM instance running on the iFrame: window.addEventListener ("message", receiveMessageFromFrame, false); console.log ("Waiting for Message 1, from iframe..."); } else { console.log ("Userscript is in the FRAMED page."); //--- Double-check that this iframe is on the expected domain: if (/puppylinux\.com/i.test (location.host) ) { window.addEventListener ("message", receiveMessageFromContainer, false); //--- Send the first message to the containing page. sendMessageFromAnIframe ( "***Message 1, from iframe***", "http://fiddle.jshell.net" ); console.log ("Waiting for Message 2, from containing page..."); } } function receiveMessageFromFrame (event) { if (event.origin != "http://www.puppylinux.com") return; console.log ('The container page received the message, "' + event.data + '".'); //--- Send message 2, back to the iframe. sendMessageToAnIframe ( "#testIframe", "***Message 2, from the container page***", "http://www.puppylinux.com" ); } function receiveMessageFromContainer (event) { if (event.origin != "http://fiddle.jshell.net") return; console.log ('The iframe received the message, "' + event.data + '".'); } /*--- Because of bugs in how Chrome presents frames to extensions, we must inject the messaging code. See bug 20773 and others. frames, top, self.parent, contentWindow, etc. are all improperly undefined when we need them. See Firefox and other browsers for the correct behavior. */ function sendMessageFromAnIframe (message, targetDomain) { var scriptNode = document.createElement ('script'); scriptNode.textContent = 'top.postMessage ("' + message + '", "' + targetDomain + '");' ; document.body.appendChild (scriptNode); } function sendMessageToAnIframe (cssSelector, message, targetDomain) { function findIframeAndMessageIt (cssSelector, message, targetDomain) { var targetIframe = document.querySelector (cssSelector) if (targetIframe) { targetIframe.contentWindow.postMessage (message, targetDomain); } } var scriptNode = document.createElement ('script'); scriptNode.textContent = findIframeAndMessageIt.toString () + 'findIframeAndMessageIt ("' + cssSelector + '", "' + message + '", "' + targetDomain + '");' ; document.body.appendChild (scriptNode); } console.log ("Script end"); 

Ensuite, visitez cette page de test à jsFiddle .

Vous verrez cela dans la console javascript:

 Démarrage de script ...
 L'utilisateur est dans la page MAIN.
 En attente du message 1, de l'iframe ...
 Fin du script
 Démarrage de script ...
 L'utilisateur est dans la page FRAMED.
 En attente du message 2, de la page contenant ...
 Fin du script
 La page conteneur a reçu le message "*** Message 1, from iframe ***".
 L'iframe a reçu le message "*** Message 2, de la page conteneur ***".