无法更改由Chrome扩展程序生成的iframe中的元素 [英] Can't change element from iframe generated by Chrome Extension
问题描述
我正在开发Chrome扩展程序。目前,有一个内容脚本返回单击元素的 XPath 。另一个内容脚本将 iframe
添加到当前的 html
页面中。在 iframe
中有一个 textarea
字段,它应该显示 xpath $ c $当用户点击它时,
的c>。
不幸的是,它不起作用。正确地生成了 xpath
(使用 console.log(path)
进行测试,但命令为:
$ b
不改变 manifest.json xpathget.js bar.js 并且生成的iframe是: 如果是 这是在控制台之后: 未捕获SecurityError:无法读取'contentDocument'属性来自'HTMLIFrameElement'的 上面已经回答 - 您无法访问iFrame的DOM从页面加载的不同于iFrame的URL,因为Some Origin Policy。 但是你可以发送消息到你的iFrame并在那里处理它以设置textarea的值。 你可以这样做: 从 在 bar.html 包含js文件,它监听你的消息并设置 所有:) PS>最好通过 I'm working on a Chrome Extension. For now, there is one content script which returns an XPath of clicked element. Another content script adds an Unfortunately it does not work. The Doesn't alter the manifest.json xpathget.js bar.js And the generated iframe is: This is the This is in console after: Uncaught SecurityError: Failed to read the 'contentDocument' property
from 'HTMLIFrameElement': Blocked a frame with origin
"http://stackoverflow.com" from accessing a frame with origin
"chrome-extension://haifbndknpepdhjlcnmpoemlmomnidpe". The frame
requesting access has a protocol of "http", the frame being accessed
has a protocol of "chrome-extension". Protocols must match.
As it already answered above - you can not access to iFrame's DOM from page loaded from different than iFrame's URL because of Some Origin Policy. But you can send message to your iFrame and process it there for setting value of textarea. You can do it bu that way: Send message from
xpathget.js In bar.html include js file, which listens your message and sets That's all :) P.S> It's better to get path to your chrome pages with 这篇关于无法更改由Chrome扩展程序生成的iframe中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! $ c $>
textarea
。你知道问题出在哪里吗?我试过了改变 bar.js
和 xpathget.js
的顺序,但它没有帮助。
{
manifest_version :2,
name:Product,
description:这是一个与product.com合作的插件,
version:1.0,
browser_action:{
default_icon:spy-icon.png,
default_popup:popup.html,
default_title:点击这里!
,
图标:{
64:spy-icon.png
},
background:{
脚本:[authentication.js]
},
content_scripts:[
{
matches:[ < all_urls>],
js:[jquery-3.1.1.min.js,xpathget.js,bar.js]
}
],
权限:[
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'
}
document.onclick = function(event){
if(event === undefined)event = window。事件; // IE hack
var target ='target'in event?event.target:event.srcElement; //另一个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 ('some_val');#这应该改变TEXTAREA
}
函数getPathTo(元素){
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 ++;
函数getPageXY(元素){
var x = 0,y = 0;
while(element){
x + = element.offsetLeft;
y + = element.offsetTop;
element = element.offsetParent;
}
return [x,y];
}
$(document).ready(function(){
$('body')。append('< iframe src =chrome -extension://some_id/bar.htmlid =xh-barclass =>< / iframe>');
});
< iframe src =chrome-extension://haifbndknpepdhjlcnmpoemlmomnidpe/bar.htmlid =xh-barclass =>这里是BAR.HTML< / iframe>
bar.html
它有助于:
<!doctype html>
< html>
< head>
< title>产品客户< / 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 =stylesheethref =https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css> ;
< link href =theme / bootstrap.css =stylesheet>
< link href =theme / usebootstrap.css =stylesheet>
< / head>
< body>
< div class =smaller>
< h1>产品客户 - 选择产品价格< / h1>
< hr>
< form class =form-horizontal>
< fieldset>
<! - 表格名称 - >
<图例>表格名称< / legend>
<! - 文字输入 - >
< div class =form-group>
< label class =col-md-4 control-labelfor =textinput>产品名称< / label>
< div class =col-md-4>
< input id =textinputname =textinputtype =textplaceholder =Nissan Patrol
class =form-control input-mdrequired =>
< / div>
< / div>
<! - Textarea - >
< div class =form-group>
< label class =col-md-4 control-labelfor =price> Price< / label>
< div class =col-md-4>
< textarea class =form-controlid =product-spy-pricename =pricereadonly>这将显示价格< / textarea>
< / div>
< / div>
<! - Button - >
< div class =form-group>
< label class =col-md-4 control-labelfor =submit>发送产品< / label>
< div class =col-md-4>
< button id =submitname =submitclass =btn btn-primary>发送< / button>
< / div>
< / div>
< / fieldset>
< / form>
< / div>
< / body>
< / html>
console.log($('#xh内容());
:阻止了一个源自框架的
http://stackoverflow.com 原产地
chrome-extension:// haifbndknpepdhjlcnmpoemlmomnidpe。请求访问的帧
具有http协议,访问的帧
具有chrome-extension协议。协议必须匹配。
发送消息xpathget.js em>
...
//替换你的setter
// $('#xh-酒吧 ')内容()找到(' #产品间谍价格some_val') ')VAL('; //#这应该改变TEXTAREA
//带
var win = document.getElementById(xh-bar)。contentWindow
win.postMessage(
{command :click,value:path},
chrome.extension.getURL('')
);
...
textarea
值:
...
函数监听器(事件){
if(event.data&& event.data.command =='click'中的command)
{
console.log (的document.getElementById( '产物间谍价格')值= event.data.value);
if(window.addEventListener){
addEventListener(message,listener,false)
} else {
attachEvent(onmessage,listener)
}
...
chrome.extension.getURL('bar.html')来获取你的chrome页面的路径。 code>而不是硬编码 - 在这种情况下,您可以在不出现问题的情况下更改应用程序ID,并在支持您的应用程序时避免许多麻烦。
iframe
into the current html
page. In this iframe
there is a textarea
field which should show the xpath
of the element
when user clicks on it. xpath
is correctly generated (tested using console.log(path)
but the command:$('#xh-bar').contents().find('#product-path').val('some_val');
textarea
. Do you know where is the problem? I've tried to change the order of bar.js
and xpathget.js
but it did not help.{
"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'"
}
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];
}
$(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
in case it helps:<!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>
console.log($('#xh-bar').contents());
...
// 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('')
);
...
textarea
value:...
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)
}
...
chrome.extension.getURL('bar.html')
instead of hardcoding it - in this case you can change application ID without problems and avoid many and many troubles while support your application.