Intercept iframe message nested iframe, cross domain - javascript

I have a webpage from domain1.com, there I have an iframe of domain2.com and then I have another iframe inside domain2.com of domain3.com
I want to intercept the messages from domain3.com in domain2.com, If domain2.com isn't inside domain1.com then the messages are received correctly, but if I have domain2.com inside domain1.com then messages from domain3.com are received by domain1.com instead of domain2.com. Is there any way to catch those messages inside domain2.com?
The structure is like this
domain1.com has inside iframe src="domain2.com"
domain2.com has inside iframe src="domain3.com"
When I access domain2.com directly it catches domain3.com messages, when I access domain1.com then messages sent from domain3.com are received by domain1.com instead of domain2.com

I tried to recreate your iframe hell. Hopefully, this is what you're looking for. This should cover the scenarios you listed above. Please let me know if I misunderstood anything.
I've also created a Plunker
index.html (domain1)
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
domain 1
<form id="form">
<input type="text" placeholder="Enter message" name="message">
<input type="submit" value="Click to send">
</form>
<iframe src="domain2.html" id="iframe" style="display:block;height:120px"></iframe>
<script>
window.addEventListener('message', function(event){
const [message, domain] = event.data.split('|');
alert(`domain1: Received ${message} from ${domain}`);
});
form.onsubmit = function() {
iframe.contentWindow.postMessage(`${this.message.value}|domain1`, '*');
return false;
};
</script>
</body>
</html>
domain2.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
domain 2
<form id="form">
<input type="text" placeholder="Enter message" name="message">
<input type="submit" value="Click to send">
</form>
<iframe src="domain3.html" id="iframe" style="display:block;height:60px"></iframe>
<script>
window.addEventListener('message', function(event){
const [message, domain] = event.data.split('|');
alert(`domain2: Received ${message} from ${domain}`);
});
form.onsubmit = function() {
iframe.contentWindow.postMessage(`${this.message.value}|domain2`, '*');
return false;
};
</script>
</body>
</html>
domain3.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
domain 3
<form id="form">
<input type="text" placeholder="Enter message" name="message">
<input type="submit" value="Click to send">
</form>
<script>
window.addEventListener('message', function(event){
const [message, domain] = event.data.split('|');
alert(`domain3: Received ${message} from ${domain}`);
});
form.onsubmit = function() {
window.parent.postMessage(`${this.message.value}|domain3`, '*');
return false;
};
</script>
</body>
</html>

Related

Set localStorage to a domain not loaded yet

Good Afternoon,
I want to set a localStorage to another domain. I used the postMessage function.
Here is the parent page :
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
var childwin;
const childname = "popup";
function openChild() {
childwin = window.open('Page2.html', childname, 'height=300px, width=500px');
}
function sendMessage(){
let msg={pName : "Bob", pAge: "35"};
// In production, DO NOT use '*', use toe target domain
childwin.postMessage(msg,'*')// childwin is the targetWindow
childwin.focus();
}
</script>
</head>
<body>
<form>
<fieldset>
<input type='button' id='btnopen' value='Open child' onclick='openChild();' />
<input type='button' id='btnSendMsg' value='Send Message' onclick='sendMessage();' />
</fieldset>
</form>
</body>
</html>
Here the children :
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
// Allow window to listen for a postMessage
window.addEventListener("message", (event)=>{
// Normally you would check event.origin
// To verify the targetOrigin matches
// this window's domain
let txt=document.querySelector('#txtMsg');
localStorage.setItem("age", event.data.pAge);
// event.data contains the message sent
txt.value=`Name is ${event.data.pName} Age is ${event.data.pAge}` ;
});
</script>
</head>
<body>
<form>
<h1>Recipient of postMessage</h1>
<fieldset>
<input type='text' id='txtMsg' />
</fieldset>
</form>
</body>
</html>
This works fine but we need 2 buttons. One to open the page, the other to post the message.
If I want to make the two methods openChild();postMessage() in the same button, it does not work.
I think it is because the page2.html is not totally loaded when we call postMessage().
How can we do ?
Best regards.
Christophe.
you can include your script when DOM loads
document.addEventListener('DOMContentLoaded', () => {
//do some functions
})

Page not found (404) in Ajax

I want to make a WEB page move screen transition in ajax .
I wrote in one.html
<html>
<head>
<meta charset="UTF-8">
<title>Top</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jquery.pjax.js"></script>
</head>
<script type="text/javascript">
$(function() {
$.pjax({
area: '#main'
});
$(document).bind('pjax:render', function() {
$('#main').attr({
'class': 'fadeInUp'
});
});
});
</script>
<body>
<p>
name
</p>
<input type="text" name="name" size="10">
<p class="button">Next</p>
</body>
</html>
in two.html
<p>
age
</p>
<input type="text" size="10">
<p class="button">Next</p>
But when I put Next button in one.html,Page not found (404)
Request URL:http://127.0.0.1:8000/app/two.html error happens.
I cannot understand why such an error happens.What is wrong in my codes?How should I fix this?
http://127.0.0.1:8000/app/two.html
so the link you can set blow:
<p class="button">Next</p>

scripts add iframe content do not have user agent style in chrome

chrome version: 58
Normally, form will have a user agent style margin-bottom: 1em;
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="utf-8" />
</head>
<body>
<form action="#">
First name:<br><input type="text" name="firstname" value="Mickey"><br>
Last name:<br><input type="text" name="lastname" value="Mouse"><br><br>
<input type="submit" value="Submit"></form>
<div>hello world</div>
</body>
</html>
with user agent style
but when I add content to iframe by scripts, the form does not have style margin-bottom: 1em;
<!DOCTYPE html>
<html>
<head>
<title>clack test</title>
<meta charset="utf-8" />
</head>
<body>
<script>
var iframe = document.createElement("iframe");
iframe.id = 'iframe';
iframe.width = '100%';
iframe.height = '886';
iframe.setAttribute("scrolling", "no");
iframe.setAttribute("frameborder", "0");
document.body.appendChild(iframe);
// find the iframe's document and write some content
var idocument = iframe.contentDocument;
idocument.open();
idocument.write("<!DOCTYPE html>");
idocument.write("<html>");
idocument.write("<head></head>");
idocument.write('<body><form action="/demo/demo_form.asp\">First name:<br><input type="text" name="firstname" value="Mickey"><br>Last name:<br><input type="text" name="lastname" value="Mouse"><br><br><input type="submit" value="Submit"></form><div>hello world</div></body>');
idocument.write("</html>");
idocument.close();
</script>
</body>
</html>
without user agent style
I wonder how to let the user agent style work in iframe. Thanks
script = document.getElementById("js");
iframe = document.createElement("iframe");
document.body.appendChild(iframe);
iframe.appendChild(script);
<script id="js">
// the script you want to inject
alert("Injected");
console.log("Injected");
</script>
try using something like this
HTML:
<script id="js">
// the script you want to inject
</script>
JS:
script = document.getElementById("js");
iframe.appendChild(script);
I made a Weave at LiveWeave.

how to implement file uploader to google drive web app code to hosted html site like instapage

I am trying to implement the example code found on https://developers.google.com/apps-script/guides/html/communication to my instapage site as an html code. Separately the web app works perfectly but after inserting it to instapage it fails to send the file to google drive.
Can you explain what did I do wrong? I was wondering if such an implemenation is possible at all. If not can you please let me know a workaround?
server.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function processForm(formObject) {
var formBlob = formObject.myFile;
var driveFile = DriveApp.createFile(formBlob);
return driveFile.getUrl();
}
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
</head>
<body>
<form id="myForm">
<input name="myFile" type="file" />
<input type="button" value="Submit"
onclick="google.script.run
.withSuccessHandler(updateUrl)
.processForm(this.parentNode)" />
</form>
<div id="output"></div>
</body>
</html>
I also attach a screenshot about the instapage implementation I tried:
enter image description here

Calling a jQuery script on the parent page when clicking on a button in an iframe

I have a page that contains a dynamically loaded <iframe>. This iframe contains a <form>.
When the user submits the <form>, a new page is loaded within the <iframe> saying Thanks.
Instead of using a second page, i want the parent page to show the Thanks message.
So basically i am in my <iframe>, and i want to call a function on the parent frame.
How can i do that ?
From an iframe, it is possible to call a function declared on the parent window using window.top.functionName(). But for this to work, both pages should be hosted on the same domain. They are subject to Same Origin Policy. That means if you want to test this example, you should use a server (wamp, xampp, etc..).
page.html (updated)
<html>
<head>
<title>Page 1</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
window.foo = function(){
alert('page 1 is executing this code');
}
$(function(){
$('body').append('<iframe src="iframeContent.html"></iframe>');
});
</script>
</head>
<body></body>
</html>
iframeContent.html
<html>
<head>
<title>Page 2</title>
</head>
<body>
i am the iframe. This is my button.
<button onclick="javascript:window.top.foo()">click me</button>
</body>
</html>
I've done a little example for you.
Here is the main page (index.html) containing the iframe
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
</head>
<body>
<input type="hidden" id="infoFormPosted" value=0 />
<iframe src="./iframe.html"></iframe>
<div id="thanks" style="display:none;">
Thanks!
</div>
</body>
</html>
And here is the iframe (iframe.html):
<html>
<head>
<title>myIframe</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#infoForm").submit(function() {
//change the value of the top document input hidden to 1
$("#infoFormPosted", top.document).val(1);
});
// if the input hidden is set to 1
if($("#infoFormPosted", top.document).val() == 1){
// show the thanks div on the top document (not in the iframe)
$("#thanks", top.document).show();
}
});
</script>
</head>
<body>
<div id="anydiv">
<form id="infoForm" action="#" method="post">
First name: <input type="text" name="fname" /><br />
Last name: <input type="text" name="lname" /><br />
<input type="submit" value="Submit" />
</form>
</div>
</body>
</html>
EDIT : An alternative is to create a function inside the main page and call it in the iframe using parent.nameOfTheFunction()
The main page (index.html)
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
showThanks = function(){
$("#thanks").show();
};
</script>
</head>
<body>
<input type="hidden" id="infoFormPosted" value=0 />
<iframe src="./iframe.html"></iframe>
<div id="thanks" style="display:none;">
Thanks!
</div>
</body>
</html>
The iframe (iframe.html):
<html>
<head>
<title>myIframe</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#infoForm").submit(function() {
//change the value of the top document input hidden to 1
$("#infoFormPosted", top.document).val(1);
});
// if the input hidden is set to 1
if($("#infoFormPosted", top.document).val() == 1){
// call showThanks function from the main frame
parent.showThanks();
}
});
</script>
</head>
<body>
<div id="anydiv">
<form id="infoForm" action="#" method="post">
First name: <input type="text" name="fname" /><br />
Last name: <input type="text" name="lname" /><br />
<input type="submit" value="Submit" />
</form>
</div>
</body>
</html>

Categories