无法更改Chrome扩展程序生成的iframe中的元素

时间:2016-10-02 17:15:46

标签: javascript jquery html iframe google-chrome-extension

我正在使用Chrome扩展程序。目前,有一个内容脚本返回单击元素的 XPath 。另一个内容脚本会在当前iframe页面中添加html。在此iframe中,有一个textarea字段,当用户点击它时,该字段应显示xpath的{​​{1}}。

不幸的是它不起作用。 element已正确生成(使用xpath测试但命令:

console.log(path)

不会改变$('#xh-bar').contents().find('#product-path').val('some_val');。你知道问题出在哪里吗?我尝试更改textareabar.js的顺序,但没有帮助。

的manifest.json

xpathget.js

xpathget.js

{
  "manifest_version": 2,
  "name": "Product",
  "description": "This is a plugin collaborating with product.com",
  "version": "1.0",
  "browser_action": {
    "default_icon": "spy-icon.png",
    "default_popup": "popup.html",
    "default_title": "Click here!"
  },
  "icons":{
    "64":"spy-icon.png"
  },
  "background": {
    "scripts": ["authentication.js"]
  },
    "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery-3.1.1.min.js","xpathget.js","bar.js"]
    }
  ],
  "permissions": [
    "activeTab",
    "https://ajax.googleapis.com/",
    "cookies",
    "<all_urls>"
  ],
  "web_accessible_resources": [
    "bar.html",
  ],
  "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}

bar.js

document.onclick = function (event) {
    if (event === undefined) event = window.event;                     // IE hack
    var target = 'target' in event ? event.target : event.srcElement; // another IE hack

    var root = document.compatMode === 'CSS1Compat' ? document.documentElement : document.body;
    var mxy = [event.clientX + root.scrollLeft, event.clientY + root.scrollTop];

    var path = getPathTo(target);
    var txy = getPageXY(target);

    alert(path);
    $('#xh-bar').contents().find('#product-spy-price').val('some_val'); # THIS SHOULD ALTER THE TEXTAREA
}

function getPathTo(element) {
    if (element.id !== '')
        return 'id("' + element.id + '")';
    if (element === document.body)
        return element.tagName;

    var ix = 0;
    var siblings = element.parentNode.childNodes;
    for (var i = 0; i < siblings.length; i++) {
        var sibling = siblings[i];
        if (sibling === element)
            return getPathTo(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
        if (sibling.nodeType === 1 && sibling.tagName === element.tagName)
            ix++;
    }
}

function getPageXY(element) {
    var x = 0, y = 0;
    while (element) {
        x += element.offsetLeft;
        y += element.offsetTop;
        element = element.offsetParent;
    }
    return [x, y];
}

生成的iframe是:

$(document).ready(function () {
    $('body').append('<iframe src="chrome-extension://some_id/bar.html" id="xh-bar" class=""></iframe>');

});

如果它有帮助,这是<iframe src="chrome-extension://haifbndknpepdhjlcnmpoemlmomnidpe/bar.html" id="xh-bar" class="">HERE IS THE BAR.HTML</iframe>

bar.html

这是在控制台之后:<!doctype html> <html> <head> <title>Product Client</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> <script src="bootstrap/bootstrap.min.js"></script> <script src="bootstrap/html5shiv.js"></script> <script src="bootstrap/respond.min.js"></script> <script src="bootstrap/usebootstrap.js"></script> <script src="popup.js"></script> <script src="productspy.js"></script> <script src="xpathget.js"></script> <script src="jsplugins/jquery.cookie.js"></script> <script src="authentication.js"></script> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"> <link href="theme/bootstrap.css" rel="stylesheet"> <link href="theme/usebootstrap.css" rel="stylesheet"> </head> <body> <div class="smaller"> <h1>Product Client - Select the product price</h1> <hr> <form class="form-horizontal"> <fieldset> <!-- Form Name --> <legend>Form Name</legend> <!-- Text input--> <div class="form-group"> <label class="col-md-4 control-label" for="textinput">Product Name</label> <div class="col-md-4"> <input id="textinput" name="textinput" type="text" placeholder="Nissan Patrol" class="form-control input-md" required=""> </div> </div> <!-- Textarea --> <div class="form-group"> <label class="col-md-4 control-label" for="price">Price</label> <div class="col-md-4"> <textarea class="form-control" id="product-spy-price" name="price" readonly>This will show the price</textarea> </div> </div> <!-- Button --> <div class="form-group"> <label class="col-md-4 control-label" for="submit">Send product</label> <div class="col-md-4"> <button id="submit" name="submit" class="btn btn-primary">Send</button> </div> </div> </fieldset> </form> </div> </body> </html>

  

Uncaught SecurityError:无法阅读&#39; contentDocument&#39;属性   来自&#39; HTMLIFrameElement&#39;:使用原点阻止了一个框架   &#34; http://stackoverflow.com&#34;从访问原始框架   &#34;铬 - 延伸:// haifbndknpepdhjlcnmpoemlmomnidpe&#34 ;.框架   请求访问具有&#34; http&#34;的协议,正在访问的帧   有一个&#34; chrome-extension&#34;的协议。协议必须匹配。

1 个答案:

答案 0 :(得分:3)

正如上面已经回答的那样 - 由于某些原始政策,您无法从不同于iFrame网址的页面访问iFrame的DOM。

但是您可以向iFrame发送消息并在那里处理它以设置textarea的值。

你可以这样做:

发送消息 xpathget.js

...
// Replace your setter
// $('#xh-bar').contents().find('#product-spy-price').val('some_val'); //# THIS SHOULD ALTER THE TEXTAREA
// with
var win = document.getElementById("xh-bar").contentWindow
win.postMessage(
    {"command":"click","value":path},
    chrome.extension.getURL('')
);
...

bar.html 中包含js文件,该文件会侦听您的邮件并设置textarea值:

...
function listener(event){
  if("command" in event.data && event.data.command=='click')
  {
      console.log(document.getElementById('product-spy-price').value=event.data.value);
  }
}

if (window.addEventListener){
  addEventListener("message", listener, false)
} else {
  attachEvent("onmessage", listener)
}
...

这就是全部:)

P.S&GT;最好使用chrome.extension.getURL('bar.html')获取Chrome页面的路径而不是硬编码 - 在这种情况下,您可以毫无问题地更改应用程序ID,并在支持您的应用程序时避免许多麻烦。