我正在尝试将活动标签页面Url设置为我在chrome.browserAction.onClicked
上注入的Iframe中的表单字段。
问题在于,由于安全策略(主页和iframe的不同来源),我无法从iframe
访问content script
。
主网页是外部页面。例如。 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,一旦加载,我想设置字段值。
我已将此链接Access iframe from content script引用,但无法找到解决方案。
任何帮助将不胜感激。
答案 0 :(得分:1)
如果您需要将简单数据传递到新创建的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
通过这种方式,您可以根据需要连接任意数量的“简单”数据
答案 1 :(得分:1)
由于您要在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) {
如果接受或不接收传入消息,您在监听器中必须使用域/来控制。
在下面的快照中(从主页面我在输入字段中写入内容并按下按钮,因此postmessage将此数据发送到在设置输入字段的其他域上运行的iframe):
答案 2 :(得分:0)
处理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
包含<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。