I have one page where I am using tag. As a source of this iframe I am passing one external webapp. Now when this app is loading, in its home page it has code which checks whether the app is loading inside frame or in parent window. If it is not in parent window then it is getting the refrence to parent window and change the location in such a way that it display itself in parent window.
Now I dont have control over this web app so I cannnot change it's home page, is there any workaround where I can stop this application to change it's parent window location. Here is the sample code I am using. I cannot give the url of the internal webapp. Before I see the alter msg "test", webapp is changing the location of the parent window.
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Example</title>
<style type="text/css">
</style>
<script type="text/javascript">
// <![CDATA[
window.onload = function()
{
alert('test');
//frames["my_iframe"].onload = function()
//{
//alert("hey");
//}
//this also works for me:
document.getElementById("my_iframe").onload = function()
{
alert("hey");
}
}
// ]]>
</script>
</head>
<body>
Testing iframe....<br>
<iframe name="my_iframe" id="my_iframe" src="http://mywebapp.com" width="100%" height="100%" ></iframe>
</body>
</html>
You are trying to do what is referred to as XSS or cross site scripting, and is, for obvious reasons, impossible in any modern browser due to security mechanisms.
This article discuss this question and offers a 'solution', so to speak.
We Done Been ... Framed!
It's actually about avoid been framed (as the webapp you talk about does) but at the end there seems to be a way to frame any page...
Related
Is there a way to determine from inside of a cross-domain iframe if the iframe is in view or not?
I was trying to achieve this using Intersection Observer API. But it seems to work only for same-domain iframe and not cross-domain. I checked the Intersection Observer API documentation(both on MDN and W3C), but couldn't find anything related to this. I hope I'm not missing anything here.
Here is the example code
Main Html Page
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Main Page</title>
</head>
<body>
<div style="margin:700px auto;text-align:center;">
<iframe marginwidth="0" marginheight="0" frameborder="0" height="250px" width="300px"
id="aax_if_aax_sidebar-btf-1" allowtransparency="true" src="http://127.0.0.1:8080/iframe.html"></iframe>
</div>
</body>
</html>
Embedded Iframe Page
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Iframe</title>
</head>
<body>
<div id="abc" style="background-color: black;width:100%;height: 100%;"></div>
<script>
setupIntersectionObserver = function (adContainer) {
console.log('setting up observer', observer);
var observer = new IntersectionObserver(
function (entries) {
console.log('observer triggered', entries);
},
{
root: null,
rootMargin: '10px',
threshold: 0
}
);
observer.observe(adContainer);
};
setupIntersectionObserver(document.getElementById('abc'))
</script>
</body>
</html>
If I run the main page locally, then the intersection observer inside the iframe works only if the page is browsed using 127.0.0.1:8080, and not for localhost:8080 (cross-domain)
Does Intersection Observer works from inside of a cross-domain iframe, with respect to the viewport?
I do not believe that there are any restrictions on cross-origin IntersectionObservers, however in my understanding they should have no explicit root set. In your case that would mean removing root: null from IntersectionObserver's configuration in the sub-frame.
It is important to note however, that your specified rootMargin value will not take effect in the cross-origin case as per the W3C it is only applied "for targets which belong to the same unit of related similar-origin browsing contexts".
You might also need to explicitly switch your JavaScript context in dev tools to the sub-frame to see the log message. Example in Chrome Dev Tools.
This use case is supported by WebKit & Blink for sure, because they have automated testing specifically for cross-origin IntersectionObserver: main frame page, sub-frame page
I create an empty popup window to which I write html code, including a title tag. This has worked before on all browsers, but Safari 5 or 6 do not work.
The code (minimized example code):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Main Window Title</title>
</head>
<body>
<p>The main page opens a second window:</p>
<SCRIPT language="JavaScript" type="text/javascript">
myWindow = window.open();
myWindow.focus();
myWindow.document.write("<html><head><title>The Other Window Title<\/title><\/head><body><p>Some text<\/p><\/body><\/html>");
myWindow.document.close();
</SCRIPT>
</body>
</html>
In Firefox this results in a main page titled "Main Window Title" and a second window titled "The Other Window Title".
But in Safari, the second window's title remains the generic "Untitled".
To me, the Safari behavior appears to be a bug, but I wonder if there is a way to make it work anyway?
(If I supply an url parameter to the window.open, where the url is a web page with a title tag, then it displays correctly, but I do of course not want that since I want it to be dynamically created.
I also tried inserting myWindow.document.title = "A new title"; but it did not have any effect in Safari, (but it has in Firefox).)
Make the url about:blank
Example:
var myWindow = window.open("about:blank")
I have a frameset with to frames left/right. The content of the frame left the one below. As you can see, I want to update the hash/fragment identifier of the left frame's parent (the uppermost window) location.
However, this leads to reloading the whole frameset in Safari/Chrome. In Firefox, the whole frameset is not reloaded, but the browsers displays "loading" continuously.
Background: The left frame shows a navigation. A click in an entry loads another HTML page in the right frame and should also update the hash in the location of the browser window so the user can bookmark pages.
How can I make this work?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Left</title>
</head>
<body>
<script type="text/javascript" charset="utf-8">
function go()
{
window.document.write('foo'); // replace document with 'foo'
window.parent.location.hash = '#foo';
}
</script>
<h1>Left</h1>
<p>
Go
</p>
</body>
</html>
You might want to try changing:
onclick="javascript:go(); return false;"
...to something like:
onclick="void(javascript:go(););"
Instead of using window.parent.location.hash just try something like this:
JS:
function go()
{
window.document.write('foo'); // replace document with 'foo'
}
HTML:
Go
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.
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