Javascript 在iFrame-Chrome扩展中设置元素值

Javascript 在iFrame-Chrome扩展中设置元素值,javascript,iframe,google-chrome-extension,Javascript,Iframe,Google Chrome Extension,我正在尝试将活动选项卡Url设置为我在chrome.browserAction.onClicked上注入的Iframe中的表单字段 问题是,由于安全策略(主页和iframe的来源不同),我无法从内容脚本访问iframe。 主网页是一个外部网页。例如,维基百科 这就是我迄今为止所尝试的 content_script.js function onExtensionMessage(request) { if (request['iconClicked'] != undefined) { v

我正在尝试将活动选项卡Url设置为我在
chrome.browserAction.onClicked
上注入的Iframe中的表单字段

问题是,由于安全策略(主页和iframe的来源不同),我无法从
内容脚本
访问
iframe
。 主网页是一个外部网页。例如,维基百科

这就是我迄今为止所尝试的

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,我将希望设置字段值

我已经提到了这个链接,但找不到解决方案


任何帮助都将不胜感激

处理iFrame和内容脚本并非易事。没有一个非常正式和好的方法来做这件事

原则 当我必须在一个特定的IFrame中执行某些操作,而不是最终在另一个加载的IFrame中执行某些操作时,我会在注入内容脚本的开始处设置一个条件

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

function runOnIframe()
{
    // Do what you want
}
这样,
runOnIframe
函数将仅在加载
myIframePage.html


例 让一页有两个iframe。第一个加载<代码>http://google.com/和第二个
chrome.runtime.getURL('popup.html')
(当然是您的IFrame)

页面
popup.html
包含一个

为了能够从后台脚本修改此输入的值,您必须发送一条消息以更正iframe。ChromeAPI不允许(在将来更新之前)向页面中的spécifique IFrame发送消息

诀窍是在注入的内容脚本中做到这一点:

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。

如果需要将简单数据传递到新创建的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脚本拆分url中:

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

通过这种方式,您可以连接任意多个“简单”数据,因为您希望在Chrome网页中动态创建的Iframe中设置一个值,并且只需使用javascript即可将数据从主页发送到Iframe

将主页设计为:


iframe{
背景:#FFF;
边框:3倍实心#000;
宽度:100%;
身高:50%;
}
window.onload=函数(){
document.getElementById('titleH2')。textContent='主页:'+window.location.href;
var myIframe=document.getElementById('myIframe').contentWindow;
document.getElementById('btnSend')。addEventListener('click',函数(e){
e、 预防默认值();
var dataToSendToIframe={
inputValue:document.getElementById('testToSend').value,
输入:“url”
}
//将消息发布到其他域上运行的Iframe
myIframe.postMessage(dataToSendToIframe,'http://localhost:63342');
});
}
主页:

发送消息

您的浏览器不支持iFrame

在该页面中,您会看到一个指向不同域的Iframe,因此出于安全原因,您无法直接对其中的内容进行操作(参考CORS)。 使用postMessage,您可以简单地将数据发送到Iframe:

myIframe.postMessage(dataToSendToIframe, 'http://localhost:63342');
另一方面,Iframe(因为您可以控制它)必须包含或类似于:


window.onload=函数(){
document.getElementById('titleH1')。textContent='Iframe位于不同的域:'+window.location.href;
var inputUrl=document.getElementById('url');
函数接收消息(e){
var origin=e.origin | | e.originalEvent.origin;
//验证消息是否从正确的来源到达,如果不是拒绝
如果(例如,原点!==”http://localhost:33232")
返回;
document.getElementById(e.data.inputId).value=e.data.inputValue;
}
window.addEventListener('message',receiveMessage);
}
不同域上的Iframe
在Iframe中,您可以看到传入消息的侦听器:

function receiveMessage(e) {
在侦听器中,您必须使用域/源来控制是否接受传入消息

在下面的快照中(从主页上,我在输入字段中写入了一些内容并按下按钮,因此postmessage会将此数据发送到在设置输入字段的不同域上运行的iframe):


清单文件中的所有帧都已设置为true。如何从内容脚本设置id=url的输入字段的值?@gaemaf:我知道了如何在内容脚本和后台页面之间传递消息。如何设置Iframe中字段的值?@gaemaf:如果使用弹出窗口,解决方案很简单,但如果单击弹出窗口之外的任何位置,弹出窗口将关闭。除了在弹出窗口上执行检查元素外,无法强制弹出窗口保持打开状态。我唯一的选择就是使用一个iframe。如果我理解的很好,您希望在iframe中插入一个页面,然后在此iframe中设置一些值。您已成功注入iframe,成功加载了其中的页面,现在您正在尝试在其中设置值?@EmrysMyrooin:是的,您是对的!因此,在我的例子中,我应该在加载iframe时调用runOnIframe()(
iframe.addEventListener('load',function(e)
)?否