there have been so many discussions in regard to access iframe with javascript. however, I can't find anything that related to an iframe without 'src' attribute.
basically, I have an iframe that doesn't have any src/link, it will be created by react and bunch of element will be inserted into this iframe on the page load.
to insert element I am using 'contentDocument!.body' which is the recommended technique.
it works fine in all browsers, except Firefox. apparently, firefox Adblock removing elements from the iframe.
so is it normal behaviour? even though iframe doesn't have an 'src' attribute and created directly in the page, shouldn't be treated as normal dom element?
I think I found the problem!
I have been creating the iframe dynamically with javascript. but look like the iframe must be rendered in the server side, and then it can be referenced and used safely to communicate with the main page
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'm trying to figure out if it's possible to programmatically change the value of sandbox for an iFrame.
From MDN iframe:
When the embedded document has the same origin as the main page, it is
strongly discouraged to use both allow-scripts and allow-same-origin
at the same time, as that allows the embedded document to
programmatically remove the sandbox attribute. Although it is
accepted, this case is no more secure than not using the sandbox
attribute.
However, changing the attribute in the parent does not successfully trigger sandboxing as that would imply in the child.
document.getElementById('myFrame').setAttribute('sandbox', 'allow-scripts');
The page loaded in that iFrame can successfully gain access to the parent, which would not be the case if sandboxing was working. The attribute does change, but the security is flawed as it does not prevent access to the patent.
console.log(window.parent.document);
The above still works in the iFrame which had the sandbox "programmatically" enabled. This is the case in both Chrome and Firefox, which would imply either intended undocumented functionality or a poorly implemented specification.
Anyone have any ideas on what would be the appropriate expectation?
Please try this fiddle : http://jsfiddle.net/yAwxy/
It's not working when the script is runned onLoad b/c the iframe is already working.
If you try onDomready, the sandboxing is applied b/c the script didn't run yet.
If you log using this fiddle:
<iframe id="myFrame" srcdoc="<script>console.log('Executing script inside iFrame')</script>">
</iframe>
And in the script
console.log('Executing script inside page')
When the script console.log('Executing script inside page') is wrapped onLoad, the outpu is :
Executing script inside iFrame
Executing script inside page
And when wrapped onDomready :
Executing script inside page
Executing script inside iFrame
See also http://jsfiddle.net/yAwxy/1/.
So to change the rules, they must be changed OndomReady
I am running into similar issues when trying to dynamically create iframe contents in Internet Explorer inside of a sandboxed iframe. I tried doing the same thing you did with using javascript to add the sandbox attribute after the iframe was already created and content placed in the iframe (using a javascript: URI in the src= attribute) but the iframe appears to keep it's attributes that were present at the time of being loaded in the page.
Internet Explorer does appear to work differently than FireFox or Chrome when it comes to applying the sandbox attribute. Chrome and FireFox will allow the contents to be dynamically created using src=javascript:function() when the sandbox="allow-scripts" is set. IE appears to apply the unique domain from the sandbox attribute during creation and considers src=javascript:function() to be not-same-origin and will not allow the dynamic creation of the iframe contents.
I am not sure why you are trying to add the sandbox attribute programmatically, but if it is an issue of trying to just load an iframe with dynamic source you can use the srcdoc attribute as well as the sandbox attribute with the only issue being that IE does not support the srcdoc attribute.
To answer your question, I do not believe it is possible to load an iframe and its contents and then add the sandbox attribute after the fact and have the iframe behave as a sandboxed iframe.
I have a problem with the script loaded from outside site. Sometimes not loaded and all script in main site is stoped by core js in browsers.
I put the script into the iframe. JS wants to eliminate the influence of the iframe to the main page and do not know how to do it.
SECURITY="restricted"?
parent.document
should give you the parent document.
If you want anything else in the parent window, use the "parent" instead of "window".
This works in firefox, but the newer IE is very restricted with javascript. I don't know if they are gonna let you do it
I have an iframe embedded on my webpage and I'd like to edit certain parts of it using javascript. Is this possible and how would I do it?
Since the iframe is loading content from another domain — no. You'll hit the same origin policy.
According to the HTML DOM spec (level 2), you can reach the child DOM by using the .contentDocument property of the iframe's DOM node.
But, of course, no browser lets you do that across domains anymore...
You can get the iframe document by doing this:
document.getElementById(iframeId).contentDocument
That is if you own the page loaded in the iframe.
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