J'essaie de définir l'URL de l'onglet actif sur un champ de formulaire dans un Iframe que j'ai injecté sur chrome.browserAction.onClicked.

Le problème est que je ne peux pas accéder au iframe à partir du content script à cause des politiques de sécurité (origine différente de la page principale et iframe). La page Web principale est une page externe. par exemple. wikipedia.com

C'est ce que j'ai essayé jusqu'à présent.

Content_script.js

function onExtensionMessage(request) {
  if (request['iconClicked'] != undefined) {
    var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
    if (!location.ancestorOrigins.contains(extensionOrigin)) {
        var urlvalue = location.href;
        var iframe = document.createElement('iframe');
        iframe.setAttribute("id", "iFrameS");
        iframe.src = chrome.runtime.getURL('popup.html');
        iframe.addEventListener('load', function (e) {
            // Either set the value of input element in Iframe 
            // here or pass an event to background.js and set it from there
            chrome.extension.sendRequest({'frameloaded': true});
        }, false);                       
        document.body.appendChild(iframe);
    }
    return;
  }
}

function initContentScript() {      
  chrome.extension.onRequest.addListener(onExtensionMessage);
}

initContentScript();

Popup.html

<form method="post">
    <input id="url" type="text">
</form>

Lorsque l'icône d'extension a été cliquée, je passe un message au script de contenu pour injecter l'iframe, une fois qu'il est chargé, je voudrais définir la valeur du champ.

J'ai référé ce lien Accéder à l'iframe à partir du script de contenu mais je n'ai pas pu Trouver une solution.

Toute aide serait appréciée.

0
Vaulstein 8 mars 2016 à 12:24

3 réponses

Meilleure réponse

Si vous avez besoin de transmettre des données simples à votre iFrame nouvellement créé, vous pouvez utiliser une chaîne de requête dans src de votre iFrame.
lors de la création de votre iFrame:

var winLoc = window.location.href; //I think this is what you want to send to your iFrame and populate field value

iframe.src = chrome.runtime.getURL('popup.html?'+winLoc );

Dans votre URL fractionnée de script iFrame:

var activeUrl = location.href.split('?')[1];  
//activeUrl now contains passed data

De cette façon, vous pouvez concaténer autant de données "simples" que vous le souhaitez

2
Wolf War 8 mars 2016 à 13:13

Gérer les IFrames et le script de contenu n'est pas une tâche facile. Il n'y a pas de manière très officielle et efficace de le faire.

Principe

Lorsque je dois effectuer une action dans un IFrame particulier et non éventuellement dans un autre IFrame chargé, je mets une condition au début du script de contenu injecté.

if(_.contains(window.location.href, "myIframePage.html")) runOnIframe()

function runOnIframe()
{
    // Do what you want
}

De cette façon, la fonction runOnIframe ne fonctionnera que sur l'iframe qui charge myIframePage.html


Exemple

Laissez une page avec remorquer des IFrames. Le premier charge http://google.com/ et le second chrome.runtime.getURL('popup.html') (votre IFrame bien sûr).

La page popup.html contient un <input id="myInput" name="myInput">.

Pour pouvoir modifier la valeur de cette entrée à partir du script d'arrière-plan, vous devez envoyer un message pour corriger l'iframe. L'API Chrome ne permet pas (jusqu'à de futures mises à jour) d'envoyer un message à un IFrame spécifique dans une page.

L'astuce consiste à le faire dans votre script de contenu injecté:

contentScript.js

if(_contains(window.location.href, "myIframePage.html")) runOnIframe

function runOnIframe()
{
    chrome.extension.onRequest.addListener(onExtensionMessage);
}

function onExtensionMessage(request)
{
    if(request.destination !== "iframe.popup.html") return

    document.getElementById("myInput").value = request.value
}

Et dans votre page de fond, il vous suffit d'envoyer l'objet:

{
    destination : "iframe.popup.html",
    value : "Some value to put in the input"
}

Le contenu de la destination peut être ce que vous voulez, c'est seulement pour reconnaître à qui vous avez envoyé le message. De cette façon, vous pouvez envoyer un message à différents iframe dans la même page en modifiant ce champ.

0
Emrys Myrooin 8 mars 2016 à 14:25

Parce que vous souhaitez définir une valeur dans votre Iframe créé dynamiquement dans une page Web dans Chrome et que vous devez le faire en utilisant uniquement du javascript, vous devez vous référer à postMessage pour envoyer vos données de la page principale à l'Iframe.

Immaginez votre page principale comme:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        iframe {
            background: #FFF;
            border: 3px solid #000;
            width: 100%;
            height: 50%;
        }
    </style>
    <script>
        window.onload = function() {
            document.getElementById('titleH2').textContent = 'Main page: ' + window.location.href;
            var myIframe = document.getElementById('myIframe').contentWindow;
            document.getElementById('btnSend').addEventListener('click', function(e) {
                e.preventDefault();
                var dataToSendToIframe = {
                    inputValue: document.getElementById('testToSend').value,
                    inputId: 'url'
                }
                // post message to the Iframe running on other domain
                myIframe.postMessage(dataToSendToIframe, 'http://localhost:63342');
            });
        }
    </script>
</head>
<body>
    <h2 id="titleH2">Main page:</h2>
    <p>
        <input id="testToSend" type="text">
    </p>
    <p>
        <button id="btnSend">Send Message</button>
    </p>

    <iframe id="myIframe" src="http://localhost:63342/Projects/StackOverflow/z.html">
  <p>Your browser does not support iframes.</p>
</body>
</html>

Sur cette page, vous voyez un Iframe pointant vers un domaine différent, vous ne pouvez donc pas agir directement sur le contenu à l'intérieur pour des raisons de sécurité (fait référence à CORS). En utilisant postMessage, vous pouvez envoyer des données à votre Iframe simplement:

myIframe.postMessage(dataToSendToIframe, 'http://localhost:63342');

De l'autre côté, l'Iframe (parce que vous pouvez le contrôler) doit contenir ou être comme:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
    </style>
    <script>
        window.onload = function() {
            document.getElementById('titleH1').textContent = 'Iframe on different domain: ' + window.location.href;
            var inputUrl = document.getElementById('url');
            function receiveMessage(e) {
                var origin = e.origin || e.originalEvent.origin;
                // verify the message arrive from the right origin, if not reject
                if (e.origin !== "http://localhost:33232")
                    return;
                document.getElementById(e.data.inputId).value = e.data.inputValue;
            }
            window.addEventListener('message', receiveMessage);
        }
    </script>
</head>
<body>
<h1 id="titleH1">Iframe on different domain</h1>
<form method="post">
    <input id="url" type="text">
</form>
</body>
</html>

Dans l'Iframe, vous pouvez voir l'écouteur des messages entrants:

function receiveMessage(e) {

Dans l'auditeur, vous devez utiliser le domaine / l'origine pour contrôler si vous acceptez ou non le message entrant.

Dans ce qui suit un instantané (à partir de la page principale, j'écris quelque chose dans le champ de saisie et j'appuie sur le bouton et un post-message envoie donc ces données à l'iframe s'exécutant sur un autre domaine définissant le champ de saisie):

enter image description here

1
gaetanoM 8 mars 2016 à 22:14