I am trying to run some javascript inside an iframe after it loads and am having trouble. I'm not sure if it means my concept of what is happening is wrong or if my code is just wrong.
What I want to do is load a javascript file in the iframe environment and then call a function. (the iframe contents are static web pages captured with singlefile and served from my server. I want to be able to pop up menus for the images in the iframe page). Is this possible, or is it blocked for security considerations? I can get the contentDocument from the iframe and see what is in it but not make any changes to it. Adding a load event listener to the iframe runs in the top-level DOM, not the iframe.
An ugly workaround would be to add a line loading the script to each of my served html files, but I'm reluctant to do that since it seems kind of fragile. Is that my only option?
you can select the iframe element and access its internal window object.
to do this first assign an id to your iframe element
<iframe id="chosen-iframe" ...></iframe>
and to access the window use the following
const iframe = document.getElementById('chosen-iframe');
const iFrameWindowElement = iframe.contentWindow;
and with access to the window, you can create a script tag that contains the script you want to inject inside the iframe
var injectedScript = iFrameWindowElement.document.createElement("script");
injectedScript.append(...);
iFrameWindowElement.document.documentElement.appendChild(script);
Related
For one of my Chrome extension project, I fetched the HTML content of another webpage in an <iframe> tag of the current webpage, by populating its src attribute dynamically. Now, I want to scrape a few values from inside the <iframe> tag. But the jQuery always shows this <iframe> tag as empty. The reason I am using is that there are a few JavaScript files inside the fetched page that I want to get executed before I start scraping. I also tried to set wait timers, but jQuery always shows <iframe> tag to be empty (though the src attribute is set).
Upon investigation, I found that the <iframe> has a strange #document value inside it, followed by the normal HTML tags. I wonder if this is the reason why the jQuery is unable to recurse through a DOM hierarchy inside the <iframe> tag.
See below screenshot of the "inspect" view of the desired <iframe> tag.
Also, the main webpage on which the <iframe> tag exists is on the same website as the newly fetch page url (albeit a different subdomain). And I'm not getting any access permission warnings in Chrome, so I do not suspect this to be a cross-domain issue.
Edit:
Even after 10 seconds wait:
console.log($("#insertHere").text());
returns empty. And,
console.log($("#insertHere").parent().html());
returns: <iframe id="insertHere" src="/courses/intro..." style="width:0;height:0;border:0; border:none;"></iframe>
You can grab iframe content with such code :
$('#insertHere').contents().find("html").html();
$('#insertHere').contents().find("#MathJax_Message").text();
If the iframe is on another domain (seems to not be in your case), cross-site-scripting (XSS) protection of your browser will block it.
The #document is a page document object for the iFrame DOM.
Try accessing the document of the iframe, e.g.
var frame = document.getElementById('#hidden-frame');
console.log(frame.document.body);
You could also try using a Content Script and allowing it in all pages with <all_urls>, which should be loaded with the iframe content, and use it to send the content to background script using messaging.
I have issue with accessing iframe that is inside another iframe.
I was trying something like this:
window.getElementById("parentIframe").contentWindow.document.getElementById("childIframe").contentWindow
But id did not worked (in my browser console i get something like "Inaccessible")
I want to know if there is a way to access nested iframe window object ?
To make things harder top parent window is on different port then iframe content. (So we have CORS to block any access from child iframe content)
Another issue is that i have no way to modify middle iframe content.
I can only embed another iframe inside of it.
My question is about accessing iframe that is inside another iframe NOT ABOUT CORS reletaed issues.
Assume we have a window and an iframe with some javascript in it. The iframe sourcecode is defined directly in "srcdoc" attribute of the iframe.
Is it possible to somehow force the browser to behave like the iframe is loaded from another domain?
I mean I don't want the javascript in the iframe to be able to access the main window via "window.parent" or anything like that, because the iframe contents is not trusted. But the problem is that it's stored on the same domain and I even want to use the same request to load both the main window and the iframe contents (with that "srcdoc" attribute).
So is it possible at all?
Thanks!
You could prepend the string:
"<script> parent = top = null; </script>"
To the srcdoc. That should prevent the rest of the code in the srcdoc form accessing the parent through window.parent and window.top.
I'm not sure if there are any other ways to access the parent of an iframe.
Is it possible ?
I've made on page with iframe, I want a script that'll click automatically inside in one iframe's link.
But I also want that script to detect half link, I mean the link which is in iframe changes everytime, but the first part of the link doesnt change, so the javascript should detect half link which doesnt change and redirect to it...
Why don't you write a "client" library and import it within iFrame. This library listen to a message from HTML5 postMessage call with certain attribute and react appropriately. Since you have access to the parent object through the event object (or window.parent), you can also send response back with the result. This way, it doesn't matter if it's cross-domain and as long as this library exists, you can communicate back-and-forth and even has the iFrame initiate if you write it properly.
I can't share the code with you since it's our proprietary library, but that's part of the idea.
If the content of your iframe is from a different domain, you can't. Allowing this would be a major security concern.
If your iframe content is in the same domain, then you can access the iframe content through its contentWindow property. You can then work with your iframe link the same way you would if the link was in the main page.
The scene: I'm writing an embeddable widget. It takes the form of a <script> tag, which builds an iframe containing everything it needs to display. The iframe has no src, and the script writes to it with theIframe.contentWindow.document.write(). This keeps the widget contained, and keeps element ids and script from conflicting with the page on which the widget is embedded.
The trick: The widget has to be able to change its size. To do this, it sets its containing iframe's style.height. This requires access to the outer page's DOM. In Firefox and IE, this is allowed, because the iframe's document and the outer document are considered to share an origin.
The twist: In Safari, however, the two documents are considered not to share an origin. The inner document is considered to be at about:blank, while the outer document is clearly using a different protocol and "domain" (if blank can be considered the domain).
The question: How can I build an iframe programmatically whose document Safari/WebKit will consider to have the same origin as the document of the window creating it?
Edit: After further experimentation, I can't find a way to programmatically create an iframe whose location is not about:blank regardless of whether I change its contents.
If I create the frame with document.createElement(), give it a src which points to a real HTML resource on the same origin called "foo.html", and document.body.appendChild() it, Safari's console shows the element as expected in the DOM, but the contents of the page do not appear, and the document is listed in the sidebar as "about:blank".
If I include the HTML for the iframe directly in the page, the contents of foo.html appear, and "foo.html" appears in the sidebar.
If I insert the HTML using document.write(), I get the same result as with document.body.appendChild().
Both programmatic versions work in Firefox.
The best suggestion I could give is to have the iframe set to a blank page on the same server (ie blank.html) and then edit the content. A pain in the rear, I know but it's a workaround.
You could also try
iframe.contentDocument.open("replace");
iframe.contentDocument.write("<b>This is some content</b>");
iframe.contentDocument.close();
However, I'm not sure if that only works in IE. Sorry I couldn't be more helpful than that.
Aha. This seems to be a bug in WebKit. When an iframe is created programmatically, its src attribute is ignored. Instead, the frame defaults to about:blank and must be directed to a URL to point elsewhere. For example:
theIframe.contentWindow.location = theIframe.src