IE post to iframe in HTA opens a new window - javascript

There are a lot of posts about this topic but most of them are because IE doesn't set the attribute name dynamically.
I'm having a different trouble: I post a form (created dynamically) with an iframe as target. The first time it works great. Then I do it for a second time and IE opens a new window with the result of form's submission. I'm pretty sure it has to do with security issues because: if I create a simple HTML file (instead of a HTA) it works great. Also, if I run the same file that doesn't work locally (http://local.host/test.hta) it works great.
Any clue of whats going on or how can I fix it? Sadly its legacy code and I can't avoid using HTA or iframes and form submiting.
Here its the simple code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<HTA:APPLICATION
ID="oHTAGeneral_v5"
APPLICATIONNAME="TEST"
ICON='Img/icono.ico'
SCROLL="no"
SINGLEINSTANCE="yes"
SELECTION='yes'
NAVIGABLE='yes'
SHOWINTASKBAR='Yes'
WINDOWSTATE='normal' />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.2.6.min.js"></script>
<script type="text/javascript">
$(function() {
var url = "http://www.some-url.com/",
first = true;
$("#frame").unbind("load");
$("#frame").load(function(){
if (first) {
first = false;
$("#frame")[0].contentWindow.document.cookie = "testCookie=dummyValue";
$("<form></form>")
.attr("target", "frame").attr("method", "POST").attr("action", url)
.css("display", "none")
.appendTo($(document.body))
.append('<input type="hidden" name="dummy" value="dummy" />')
.submit();
return;
}
// Other stuff
});
$("<form></form>")
.attr("target", "frame").attr("method", "POST").attr("action", url)
.css("display", "none")
.appendTo($(document.body))
.append('<input type="hidden" name="dummy" value="dummy" />')
.submit();
});
</script>
</head>
<body>
<iframe id="frame" name="frame" width="200" height="50"></iframe>
</body>
</html>

You can try to use application="yes" attribute within iframe tag. Iframes without the said attribute are considered as unsafe in HTA, and all interaction between iframe and main window is blocked.

Related

How do I remove iframe within itself by using javascript

I know that there are several similar questions, but I have to ask the question again with attached code because of being unable to work out.
I have two .xhtml file in JSF project. One is mainPage.xhtml has a button that generates dynamic html code to create an iframe (iFramePage.xhtml) and show it on the browser;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<h:outputStylesheet library="css" name="style.css" />
<script type="text/javascript">
/** Create dynamic iframe HTML code for iFramePage.xhtml **/
function createIFrameHTML(){
document.getElementById("iFrameContainer").innerHTML = '<div id="iframe0"><iframe src="iFramePage.xhtml" width="450px" height="300px"></iframe></div>';
}
/** Close iFrame **/
function removeElement() {
/*Both lines work properly when I call inside this page, */
/*..however it does not work by calling from iFramePage.xhtml */
//document.getElementById("iFrameContainer").removeChild("iframe0");
$('iframe0').remove();
}
</script>
</h:head>
<body>
<f:view>
<h:form id="mainForm">
<!-- Control Menu -->
<div id="cntrMenu">
<h:commandButton id="cntrBtn1"
onclick="createIFrameHTML();return false;"></h:commandButton>
<h:commandButton id="cntrBtn2"
onclick="removeElement();return false;"></h:commandButton>
</div>
<div id="iFrameContainer">
<!-- an iframe will be generated by createIFrameHTML() -->
</div>
</h:form>
</f:view>
</body>
</html>
The other page is iFramePage.xhtml that has some html and javascript code;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<h:outputScript name="......js" />
<h:outputStylesheet name="....css" />
<script>
/** Close iFrame.**/
function closeSelf() {
/* Two lines works properly, however third line does not work!*/
//window.top.location.href = "HIDDEN";
//parent.document.location.href = "HIDDEN";
parent.removeElement();
}
</script>
</h:head>
<body>
<input jsfc="h:commandButton" id="exitBtn" value="Kapat" onclick="closeSelf();" />
</body>
</html>
I can generate the iframe by clicking "cntrBtn1" button and removing by clicking "cntrBtn2" inside mainPage.xhtml. However, I need to remove the iframe within itself (iFramePage.xhtml). When I click "exitBtn" in iFramePage.xhtml, the iframe does not disappear. There is nothing about cross-domain, because mainPage.xhtml and iFramePage.xhtml are in the same JSF project, even in the same directory. I can redirect the parent page (looks at two lines in closeSelf() in iFramePage.xhtml), but I cannot remove the iframe by using parent element, why! Please, help me :)
Communicate between the parent and iframe using window.postMessage.
Replace the closeSelf() function in iframe page to the following :
function closeSelf() {
parent.window.postMessage("removetheiframe", "*");
}
and on the parent page, add the following code to listen when the iframe sends a message :
function receiveMessage(event){
if (event.data=="removetheiframe"){
var element = document.getElementById('iframe-element');
element.parentNode.removeChild(element);
}
}
window.addEventListener("message", receiveMessage, false);
You can also check the origin of postMessage by event.origin to make sure that the right iframe requested to remove the iframe.

onload for a jsp inside IFrame was setting the iframe to entire page/browser

I have an IFrame in a DIV with its SRC attribute being dynamically set by a JS function. So, if src="file.jsp", then an onload function(inside the body in file.jsp) that contains adjustments to some styles inside the file.jsp was hovering IFrame all over the webpage once it was done with the function triggered by onload. i.e., iframe is spreading all over the webpage. Please let me know what needs to be done to preserve the IFrame position after the onload function.
The Code in my onload function is as shown
function load() {
var url = window.location.href;
if (url.indexOf('iip') > -1) {
document.getElementById('peLibraryTreeDiv').style.width = "596px";
parent.document.getElementById('privateEquityDiv').style.width =
"96.9%";
parent.document.getElementById('privateEquityDiv').style.top =
"77px";
}
}
this is a perfectly valid and working example
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function changeIframe(newLocation){
document.getElementById("myIframe").src=newLocation;
}
</script>
</head>
<body onload="changeIframe('http://www.example.com')">
<div style="width:650px;float:auto;border:1px dotted #cccccc;">
<iframe id="myIframe" src="http://www.ebay.co.uk/" width="100%" height=750px marginwidth=0 marginheight=0 hspace=0 vspace=0 frameborder=1 scrolling=auto>
<p>Your browser does not support iframes.</p>
</iframe>
</div>
</body>
</html>
please note that some websites cannot be added as src to an iframe like http://www.google.com (not sure why, I have made a question on SO here can't add google.com as src to an IFrame)

Unsecure content over https

I am getting the mixed content warning on a webapp I am working on when using the jsDatePick.
I have used fiddler and can confirm the problem is not caused by any image sources.
When a date is selected the following line is run:
window.location.href = "\something\something\day?=date" + this.getSelectedDateFormatted();
Would this be the cause of the problem?
The problem seems to be with a JsDatePick .js file. I have the same issue (mixed content). I'm unfortunately forced to use IE 8 for this project. The parent page is https, and I've minimalized the page to the following (this minimal page still gets the mixed content pop-up:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<script type="text/javascript" src="jsDatePick.min.1.3.js"></script>
<script type="text/javascript" src="jquery-1.2.1.pack.js"></script>
<script type="text/javascript">
window.onload = function()
{
new JsDatePick({
useMode:2,
target:"date_range1",
dateFormat:"%m/%d/%Y"
});
};
</script>
</head>
<body>
<h1> Hey</h1>
</body>
</html>
No, because the protocol is not specified it should inherit the protocol of the parent page. Look for anything calling "http://" instead of "https://" in your page source.

Why does appending a <script> to a dynamically created <iframe> seem to run the script in the parent page?

I'm attempting to create an <iframe> using JavaScript, then append a <script> element to that <iframe>, which I want to run in the context of the <iframe>d document.
Unfortunately, it seems I'm doing something wrong - my JavaScript appears to execute successfully, but the context of the <script> is the parent page, not the <iframe>d document. I also get a 301 Error in Firebug's "Net" tab when the browser requests iframe_test.js, though it then requests it again (not sure why?) successfully.
This is the code I'm using (live demo at http://onespot.wsj.com/static/iframe_test.html):
iframe_test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title><iframe> test</title>
</head>
<body>
<div id="bucket"></div>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#bucket').append('<iframe id="test"></iframe>');
setTimeout(function() {
var iframe_body = $('#test').contents().find('body');
iframe_body.append('<scr' + 'ipt type="text/javascript" src="http://onespot.wsj.com/static/iframe_test.js"></scr' + 'ipt>');
}, 100);
});
</script>
</body>
</html>
iframe_test.js
$(function() {
var test = '<p>Shouldn\'t this be inside the <iframe>?</p>';
$('body').append(test);
});
One thing that seems unusual is that the the code in iframe_test.js even works; I haven't loaded jQuery in the <iframe> itself, only in the parent document. That seems like a clue to me, but I can't figure out what it means.
Any ideas, suggestions, etc. would be much appreciated!
Had the same problem, took me hours to find the solution.
You just need to create the script's object using the iframe's document.
var myIframe = document.getElementById("myIframeId");
var script = myIframe.contentWindow.document.createElement("script");
script.type = "text/javascript";
script.src = src;
myIframe.contentWindow.document.body.appendChild(script);
Works like a charm!
I didn't find an answer to my original question, but I did find another approach that works even better (at least for my purposes).
This doesn't use jQuery on the parent page (which is actually a good thing, as I'd prefer not to load it there), but it does load jQuery in the <iframe> in an apparently completely valid and usable way. All I'm doing is writing over the <iframe>'s document object with a new one created from scratch. This allows me to simply include a <script> element in a string which I then write to the <iframe>'s document object.
The code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>frame</title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript">
// create a new <iframe> element
var iframe = document.createElement('iframe');
// append the new element to the <div id="bucket"></div>
var bucket = document.getElementById('test');
bucket.appendChild(iframe);
// create a string to use as a new document object
var val = '<scr' + 'ipt type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></scr' + 'ipt>';
val += '<scr' + 'ipt type="text/javascript"> $(function() { $("body").append("<h1>It works!</h1>"); }); </scr' + 'ipt>';
// get a handle on the <iframe>d document (in a cross-browser way)
var doc = iframe.contentWindow || iframe.contentDocument;
if (doc.document) {
doc = doc.document;
}
// open, write content to, and close the document
doc.open();
doc.write(val);
doc.close();
</script>
</body>
</html>
I hope this helps someone down the road!
The answer to the original question is simple - the execution of the script is done by jquery, and since jquery is loaded in the top frame, this is where the script runs too, no matter where you are appending it. A smarter implementation of jquery can no doubt be made to use the correct window object, but for now things are how they are.
As to the workarounds, you already have two good answers (even if one is your own). What I might add is that you can use one of those workarounds to include jquery.js in the iframe, and then get that jquery object instead of the top one to insert your additional markup... but that may very well be overkill too.

How to dynamically change the "src" or "data" for a PDF Object / Embed file using JavaScript?

I have a web application that is dynamically loading PDF files for viewing in the browser.
Currently, it uses "innerHTML" to replace a div with the PDF Object. This works.
But, is there a better way to get the ID of the element and set the "src" or "data" parameter for the Object / Embed and have it instantly load up a new document?
I'm hoping the instance of Adobe Acrobat Reader will stay on the screen, but the new document will load into it.
Here is a JavaScript example of the object:
document.getElementById(`divPDF`).innerHTML = `<OBJECT id='objPDF' DATA="'+strFilename+'" TYPE="application/pdf" TITLE="IMAGING" WIDTH="100%" HEIGHT="100%"></object>`;
Any insight is appreciated.
I am not sure if this will work, as I have not tried this out in my projects.
(Looking at your JS, I believe you are using jQuery. If not, please correct me)
Once you have populated the divPDF with the object you might try the code below:
$("objPDF").attr({
data: "dir/to/newPDF"
});
Again, I am not sure if this will work for your particular needs but if you attach this code to an event handler you can switch out the data of the object.
You could also wrap it in a function to be used over and over again:
function pdfLoad(dirToPDF) {
$("objPDF").attr({
data: dirToPDF
});
}
If the handler for the PDF is acrobat (it doesn't have to be), it exposes a JS interface that is documented here:
http://www.adobe.com/devnet/acrobat/pdfs/js_api_reference.pdf
See if you can call openDoc(urlToPdf) on document.getElementById('objPDF') -- even if this works, it only works when Acrobat is being used to handle 'application/pdf'
#lark
A slight correction:
$('#objPDF').attr('data','dirToPDF');
The # specifies the objPDF is an ID and not an element name. Though I still don't know if this will work.
#Tristan
Take a look at the jQuery Media plugin. It mentions support for PDF as well, though I have never used it.
Open a PDF-Link in a external window PDFN with a external PDF-Reader.EXE:
Clicking on the following button:
<FORM action="">
<INPUT type="button" value="PDF file"
onclick="window.open('http://www.Dku-betrieb.eu/Pdfn.html',
'PDFN', 'width=620, height=630')">
</FORM>
opens this frameset Pdfn.html in an external window:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html lang="de">
<meta http-equiv="refresh" content="12;url=http://www.dku-betrieb.eu/Pdfn1.html">
<head>
<title>Reader</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<frameset>
<frame src="http://www.dku-betrieb.eu/File.pdf" frameborder=0 name="p1">
</frameset>
</HTML>
which refreshes in 12 seconds to the download of the PDF-Reader:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html lang="de">
<head>
<title>Reader</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<frameset >
<frame src="http://www.dku-betrieb.eu/PDFReader.exe" frameborder=0 name="p2">
</frameset>
</HTML>
showing as result the PDF-file in the external window PDFN.
function pdfLoad(datasrc) {
var x = document.getElementById('objPDF');
x.data = datasrc;
}
This worked for me

Categories