我正在使用Chrome扩展程序。目前,有一个内容脚本返回单击元素的 XPath 。另一个内容脚本会在当前iframe
页面中添加html
。在此iframe
中,有一个textarea
字段,当用户点击它时,该字段应显示xpath
的{{1}}。
不幸的是它不起作用。 element
已正确生成(使用xpath
测试但命令:
console.log(path)
不会改变$('#xh-bar').contents().find('#product-path').val('some_val');
。你知道问题出在哪里吗?我尝试更改textarea
和bar.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;的协议。协议必须匹配。
答案 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,并在支持您的应用程序时避免许多麻烦。