簡體   English   中英

在iFrame中設置元素值-Chrome擴展程序

[英]Set element value in iFrame - Chrome Extension

我試圖將活動標簽Url設置為我在chrome.browserAction.onClicked注入的iframe中的表單字段。

問題是,我無法訪問iframecontent script ,因為安全策略(主頁和iframe的不同來源)的。 主頁是一個外部頁面。 例如。 wikipedia.com

到目前為止,這是我嘗試過的。

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>

單擊擴展程序圖標后,我將消息傳遞到內容腳本以注入iframe,一旦加載iframe,我將要設置字段值。

從內容腳本中引用了此鏈接Access iframe,但是找不到解決方案。

任何幫助,將不勝感激。

如果需要將簡單數據傳遞到新創建的iFrame,則可以在iFrame的src中使用查詢字符串。
創建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 );

在您的iFrame腳本拆分網址中:

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

這樣,您可以隨意連接多個“簡單”數據

因為您要在Chrome瀏覽器的網頁中動態創建的Iframe中設置一個值,並且只需要使用javascript才能執行此操作,因此需要引用postMessage將數據從主頁分發到Iframe。

像這樣想象您的主頁:

<!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>

在此頁面中,您會看到一個指向其他域的Iframe,因此出於安全原因(請參閱CORS),您不能直接對其中的內容執行操作。 使用postMessage可以簡單地將數據發送到iframe:

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

另一方面,iframe(因為您可以控制它)必須包含以下內容:

<!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>

在iframe中,您可以看到傳入消息的偵聽器:

function receiveMessage(e) {

在偵聽器中,您必須使用域/來源來控制是否接受傳入消息。

在下面的快照中(從主頁開始,我在輸入字段中寫了一些東西,然后按一下按鈕,因此后消息將這些數據發送到在另一個域中設置輸入字段的iframe上運行):

在此處輸入圖片說明

處理IFrame和內容腳本並非易事。 沒有一個非常正式和好的方法來做到這一點。

原理

當我必須在特定的IFrame中執行某些操作,而不要最終在其他已加載的IFrame中執行某些操作時,我會在“已插入內容腳本”的開頭放置一個條件。

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

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

這樣, runOnIframe函數將僅在正在加載myIframePage.html的iframe上運行


例子

讓頁面包含兩個iframe。 第一個加載http://google.com/ ,第二個chrome.runtime.getURL('popup.html') (當然是您的IFrame)。

頁面popup.html包含<input id="myInput" name="myInput">

為了能夠從后台腳本修改此輸入的值,您必須發送一條消息以更正iframe。 Chrome API不允許(直到將來更新)將消息發送到頁面中的spécifiqueIFrame。

訣竅是在注入的內容腳本中執行此操作:

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
}

在背景頁面中,您只需發送對象:

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

目的地的內容可以是您想要的,僅用於識別發送消息的人。 這樣,您可以通過更改此字段將消息發送到同一頁面中的不同iframe。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM