Userscript绕过用于访问嵌套iframe的同源策略 [英] Userscript to bypass same-origin policy for accessing nested iframes
问题描述
在下面的HTML模型中,嵌套的iframe源自不同的子域。这导致诸如错误的消息:拒绝访问属性文档的权限
< HTML>
< head>
< title>< / title>
< / head>
< body>
< div>
< iframe id =outer_iframe_1src =https://subdomain1.example.com>< / iframe>
< / div>
< div>
< iframe id =outer_iframe_2src =https://subdomain2.example.com>
< div>
< iframe id =inner_iframe_2src =https://subdomain4.example.com>< / iframe>
< / div>
< / iframe>
< / div>
< div>
< iframe id =outer_iframe_3src =https://subdomain3.example.com>< / iframe>
< / div>
< / body>
< / html>
我打算在嵌套的iframe中获取和修改值(例如 inner_frame_2
)与一个Userscript,所以绕过同源策略应该是可能的。但是 GM_xmlhttpRequest
的例子似乎依赖于GET / POST请求,而我只想处理这些iframe中已经加载的页面数据。
我是否误解 GM_xmlhttpRequest
,或者我应该采用另一种方法?
我认为唯一可以做到这一点的方法是使用
PS:不是
< iframe id =outer_iframe_2src =https:/ /subdomain2.example.com\">
< div>
< iframe id =inner_iframe_2src =https://subdomain4.example.com>< / iframe>
< / div>
< / iframe>
In the following HTML mockup, the nested iframes are originating from different subdomains. This is causing messages such as error: Permission denied to access property "document"
<html>
<head>
<title></title>
</head>
<body>
<div>
<iframe id="outer_iframe_1" src="https://subdomain1.example.com"></iframe>
</div>
<div>
<iframe id="outer_iframe_2" src="https://subdomain2.example.com">
<div>
<iframe id="inner_iframe_2" src="https://subdomain4.example.com"></iframe>
</div>
</iframe>
</div>
<div>
<iframe id="outer_iframe_3" src="https://subdomain3.example.com"></iframe>
</div>
</body>
</html>
I am intending to fetch and modify values within the nested iframes (eg. inner_frame_2
) with a Userscript, so bypassing the Same-origin policy should be possible. But examples of GM_xmlhttpRequest
seem to rely on GET/POST requests, whereas I only want to deal with the already loaded page data within these iframes.
Am I misunderstanding GM_xmlhttpRequest
, or is there another approach I should be taking here?
I think the only way you can do it, is by using the window.postMessage()
method to send messages with data from iframes to the top window. To catch each iframe inside Greasemonkey script see Brock Adams answer on Apply a Greasemonkey userscript to an iframe?; you'll have to use the GM @match
directive like this:
// @match http://subdomain1.example.com/*
or
// @match *.example.com/*
Then you can check if the current window is the top window, and/or check the document.domain
to identify the iframe:
// ==UserScript==
// @name New Userscript
// @match http://main-domain.something
// @match *.example.com/*
// ==/UserScript==
(function() {
'use strict';
if (window.top === window.self) {
// Here we are at the top window and we setup our message event listener
}
else {
// Here we get inside the iframes.
// We can address and check each iframe url with document.domain
}
})();
We need to hook an event for "message"
to the top window that will handle each message it receives from the iframes with the data:
window.addEventListener("message", function(event) {
// do something with the event.data
}, false);
And we can identify the iframes by using document.domain
; do whatever manipulation we need to the iframe elements; retrieve all the data we want and send the message to the top window:
window.top.postMessage({
// data object we send to the top window
}, "*");
I created a demo to try this and it works pretty well. My top window URL is http://zikro.gr/dbg/gm/iframes/main.php
and the subdomains are like http://subdomain1.zikro.gr/
. The top window HTML is identical to yours with my iframe urls and the GM script:
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://zikro.gr/dbg/gm/iframes/main.php
// @match *.zikro.gr/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
if (window.top === window.self) {
// Here we are at the top window and we setup our message event listener
document.body.style.backgroundColor = "#f00"; // Just a UI change to identify the top window
window.addEventListener("message", function(event) {
window.console.log("This is data from '" + event.data.title +
"'; with message '" + event.data.message +
"'; with data '" + event.data.data +"'" +
"'; from domain '" + event.data.domain + "'");
}, false);
}
else {
// Here we get inside the iframes.
// We can address and check each iframe url with document.domain
document.body.style.backgroundColor = "#0f0"; // Just a UI change to identify the iframe window
// We change something inside the iframe
var dataDiv = document.getElementsByTagName('div')[0];
dataDiv.innerHTML += " with a change!";
// And we post a message to the top window with all the data we want inside an object
window.top.postMessage({
title: document.title,
domain: document.domain,
message: "Hello from, iframe - " + document.title,
data: dataDiv.innerText
}, "*");
}
})();
And a screen capture for those who don't have Greasemonkey/Tampermoney installed to test this:
PS: It's not valid to add elements directly inside an iframe tag like this:
<iframe id="outer_iframe_2" src="https://subdomain2.example.com">
<div>
<iframe id="inner_iframe_2" src="https://subdomain4.example.com"></iframe>
</div>
</iframe>
这篇关于Userscript绕过用于访问嵌套iframe的同源策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!