I have two documents, one of which is embedded into the other with an iframe. I'm trying to use this code to access the img tag inside the iframe, however, I cannot use the document.getElementById function on the iframe element:
iframes = document.getElementsByTagName("iframe")
spaces = iframes[0].contentWindow.document;
spaces = spaces.getElementsByTagName("img")
for (var i=0, max=spaces.length; i < max; i++) {
alert(spaces[i].innerHTML)
}
alert(spaces)
var x = document.getElementById("frame");
var y = (x.contentWindow || x.contentDocument);
if (y.document)y = y.document;
alert(y.body.innerHTML)
spaces returns [object HTMLCollection] and y returns [object HTMLDocument]
So, if you're on the same domain as your iframe content, you can use
document.getElementById('my-iframe').contentWindow.document.getElementById(...)
If you're not on the same domain, you can't access/manipulate iframe content for security reasons. Otherwise malicious folks could throw up an iframe that looks like Facebook or something and steal other folk's info.
If you're not on the same domain but own both domains you're using, you can set up messaging between the two frames. And use the parent to message the child for information/manipulation.
Related
A simple task in JavaScript is to open a new window and writing inside. But I need to write in a dom element, a div with an ID.
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
Than I try something...
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
I did it to see if the object "novoForm" is valid. But nothing is written in "monitor" div. I also try using onload event with no success. I'm wondering if it's some security restriction or am I missing something...
You've done it right, but you do need to be sure to use onload (or poll), because it takes a moment for the page to get loaded in the new window.
Here's a full working example: Live Copy | Source
(function() {
document.getElementById("theButton").onclick = function() {
var novoForm = window.open("http://jsbin.com/ugucot/1", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
novoForm.onload = function() {
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
};
};
})();
I'm wondering if it's some security restriction or am I missing something...
Not in your example as shown, no, because the page is clearly being loaded from the same origin. If the URL were from a different origin, then yes, you'd be running into the Same Origin Policy, which prohibits cross-origin scripting. You can relax that via the document.domain property, having both the window containing the code above and the window being loaded setting document.domain to the same value. From the link above:
If two windows (or frames) contain scripts that set domain to the same value, the same-origin policy is relaxed for these two windows, and each window can interact with the other. For example, cooperating scripts in documents loaded from orders.example.com and catalog.example.com might set their document.domain properties to “example.com”, thereby making the documents appear to have the same origin and enabling each document to read properties of the other.
More about document.domain can be found on MDN. Note that it only works where both documents share a common parent domain, e.g., so it works for app1.example.com and app2.example.com if they both set to example.com, but not for example1.com and example2.com because they have not common value they can set.
Alternatively, this is a solution:
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var teste = function(){
var mon = novoForm.document.getElementById("monitor");
if(typeof(mon)!="undefined"){
//novoForm.alert("Achei!");
var h = novoForm.innerHeight;
var strh = String(h - 40 - 30)+'px';
novoForm.document.getElementById("pagina").style.height = strh;
novoForm.document.getElementById("monitor").innerHTML = '<p class="legenda">© NetArts | gustavopi</p>';
clearInterval(id);
}
}
var id = setInterval(teste, 100);
This will do the job. Not a "pretty" solution to me, but it works!
Depends on what url you try to load into the new window. #T.J is right on that. Also note that if you just want to load a blank document you can load "about:blank" into the url. The only difference is that you would use outerWidth since you haven't loaded an actual document.
var novoForm = window.open("about:blank", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var w = novoForm.outerWidth;
var h = novoForm.outerHeight;
novoForm.document.body.innerHTML = 'Janela: '+w+' x '+h;
I got this iframe:
<iframe id="frami" src="http://192.168.178.22/file.html"></iframe>
which contains the text:
var m1_enable="1"; var m1_x="0"; var m1_y="570"; var m1_w="1920"; var m1_h="510"; var m1_sensitivity="50"; var m1_threshold="0";
How can I check if m1_enable="1" exists in the iframe?
I tried this now:
iframe_html = document.getElementById('frami').contentWindow.document.body.innerHTML;
if(iframe_html.includes("var")){
alert();
}
else{
}
iframe tag has a property called contentDocument that returns the document object generated by an iframe and another called contentWindow that returns the window object generated by an iframe. You can check if "m1_enable="1" by
var x = document.getElementById("frami");
var y = (x.contentWindow || x.contentDocument);
if (y.document) y = y.document;
if (y.body.textContent.indexOf('m1_enable="1"')>-1){
alert('found the phrase'
}
You can get the HTML from iframe with:
iframe_html = document.getElementById('iframe').contentWindow.document.body.innerHTML
And check if it includes m1_enable="1" with:
iframe_html.includes("m1_enable='1'")
This will work only if the frame source is on the same domain. If it is from a different domain, cross-site-scripting (XSS) protection will kick in.
If your iframe is on the same domain it is document.getElementById('frami').contentWindow['m1_enable'] (if this isn't null, compare with 1 with ==1).
otherwise, look at window.postMessage
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
I've been trying to make an extension that gets the source of video players on the web by looking at the iframe sources, however it turns out a lot of those iframes have iframes nested inside of them where the actual video is, or sometimes it's even another iframe deep. I've been trying to look deeper with things js like this:
var iframe = document.getElementsByTagName("iframe");
var nestedframes = iframe.getElementsByTagName("iframe");
and like this:
var iframe = document.getElementsByTagName("iframe");
var innerDoc = iframe.contentWindow.webbody.innerHTML;
var nestedframes = innerDoc.getElementsByTagName("iframe");
but they return this error: contentscript.js:6 Uncaught TypeError: iframe.getElementsByTagName is not a function.
If anyone has any ideas that would be greatly appreciated.
getElementsByTagName() method gets all elements on the document with the specified tag name. It means that it gives you a list of elements.
So you should itearate over it or select single element to call another DOM method. (Notice [0])
var iframe = document.getElementsByTagName("iframe")[0];
var nestedframes = iframe.getElementsByTagName("iframe");
With PhantomJS, I want to print the html source of a webpage like Firebug does. Interpreted with iframes.
var page = require('webpage').create();
page.open('http://google.com', function () {
console.log(page.content);
phantom.exit();
});
This only seem to shows the interpreted HTML without iframes html. And use evaluate can't help because my iframes are in another domain so I think javascript with not have access to them.
I found that going through frames to get content did not work because page.framesCount in phantomjs counts only the child frames and not the main frame. Here is working code to display the HTML of all frames:
// Apparently framesCount doesn't include the main frame so add 1
var frameCount = page.framesCount + 1
var html = page.frameContent + '\n\n'
for (var i = 1; i < frameCount; ++i) {
page.switchToFrame(i)
html += page.frameContent + '\n\n'
}
One last important thing, if you don't want the source but want to access the iframe DOM even if it's in another domain do it like this:
phantomjs --web-security=no
The code to access the iframe body is:
var i = document.getElementsByTagName('iframe')
var body = i[0].contentWindow.document.body
A simple task in JavaScript is to open a new window and writing inside. But I need to write in a dom element, a div with an ID.
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
Than I try something...
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
I did it to see if the object "novoForm" is valid. But nothing is written in "monitor" div. I also try using onload event with no success. I'm wondering if it's some security restriction or am I missing something...
You've done it right, but you do need to be sure to use onload (or poll), because it takes a moment for the page to get loaded in the new window.
Here's a full working example: Live Copy | Source
(function() {
document.getElementById("theButton").onclick = function() {
var novoForm = window.open("http://jsbin.com/ugucot/1", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
novoForm.onload = function() {
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
};
};
})();
I'm wondering if it's some security restriction or am I missing something...
Not in your example as shown, no, because the page is clearly being loaded from the same origin. If the URL were from a different origin, then yes, you'd be running into the Same Origin Policy, which prohibits cross-origin scripting. You can relax that via the document.domain property, having both the window containing the code above and the window being loaded setting document.domain to the same value. From the link above:
If two windows (or frames) contain scripts that set domain to the same value, the same-origin policy is relaxed for these two windows, and each window can interact with the other. For example, cooperating scripts in documents loaded from orders.example.com and catalog.example.com might set their document.domain properties to “example.com”, thereby making the documents appear to have the same origin and enabling each document to read properties of the other.
More about document.domain can be found on MDN. Note that it only works where both documents share a common parent domain, e.g., so it works for app1.example.com and app2.example.com if they both set to example.com, but not for example1.com and example2.com because they have not common value they can set.
Alternatively, this is a solution:
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var teste = function(){
var mon = novoForm.document.getElementById("monitor");
if(typeof(mon)!="undefined"){
//novoForm.alert("Achei!");
var h = novoForm.innerHeight;
var strh = String(h - 40 - 30)+'px';
novoForm.document.getElementById("pagina").style.height = strh;
novoForm.document.getElementById("monitor").innerHTML = '<p class="legenda">© NetArts | gustavopi</p>';
clearInterval(id);
}
}
var id = setInterval(teste, 100);
This will do the job. Not a "pretty" solution to me, but it works!
Depends on what url you try to load into the new window. #T.J is right on that. Also note that if you just want to load a blank document you can load "about:blank" into the url. The only difference is that you would use outerWidth since you haven't loaded an actual document.
var novoForm = window.open("about:blank", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var w = novoForm.outerWidth;
var h = novoForm.outerHeight;
novoForm.document.body.innerHTML = 'Janela: '+w+' x '+h;