I'm using the Google Chrome JavaScript console and I was just looking at the Gmail page and just practicing manipulating the DOM. However, when I do the following it just comes back as null:
document.getElementById('gbx3');
There is a div element in the page that has an id of 'gbx3' - so why is it returning null? What would/could be causing this? The same thing occurs using the Firefox web console.
If you try and access the 'gb' id (this is the main top toolbar) in the same Gmail page it comes back null, but if you access this element at google.com it will come back with the element.
GMail is composed of frames. This one works:
frames[3].document.getElementById('gbx3');
In general, if you know the ID of the iframe element, the contentDocument property can be used (provided that you don't have same-origin problems, and the document is loaded):
document.getElementById('hist_frame').contentDocument.getElementById('gbx3');
As per my comment:
My best bet is that gbx is inside the iframe that contained the search
result, and document.getElementById works on the same scope as your
console
You can search all the frames to find what you need:
for(var i = 0; i < frames.length; i++) {
var curDoc = frames[i].document;
if(curDoc.getElementById('gbx')) console.log(curDoc.getElementById('gbx'));
}
Related
So I've tried to do a bunch of research and can't seem to find the correct answer for my question so I wanted to reach out and see if anyone knows much.
What I'm attempting to achieve:
Check the contents inside an iFrame and return a boolean whether there is content or not.
Here is what I've attempted:
function check_iframe_body_content(element) {
let has_content = false;
let iframe = element.contents().find('body');
console.log(iframe);
if (iframe.length > 0) {
has_content = true;
}
return has_content;
}
The element is the iFrame return, which will be an array:
When the script tags are disabled, I get the following return:
When the script tags are enabled, I get the following return:
How can I properly determine if the <body> is empty and when it's not? I've tried to do .length on multiple different occasions and each time it comes back as has_content = true because it finds the body element, but it's actually empty.
All help will be appreciated!
You wont have access to the content inside iframe if it's loaded from another website as it's a major security breach.
if that was possible a website could add an iframe to google.com and get access to user personal information like their email address, name and etc.
depending on why you want to check content of iframe, there might be other workarounds.
I am using one of those vulnerable practice sites on Kali Linux and when I inspected the source page I noticed the following variable var pathName = document.getElementById("path") The value of pathName is hidden and it is up to me to find it as these sites are there for people to practice their ethical hack skills
So in the Chrome Web Browser console, I type in document.getElementById("path").value but I keep getting return null. I don't understand why, like do I need to do like window.ontop?
Any help would be great!
Make you sure you have an input in DOM with id="path" attribute value.
For example -
<input id="path">
If that is not present in the DOM then getElementById will always return null.
You can open Chrome-Dev Tool and search this #path in Elements tab. That should highlight that input, if it is not then you are targeting wrong element.
If document.getElementById("path").value returns null, your element was found. It might not be an input element, so might not contain a value field.
Try typing JSON.stringify(document.getElementById("path")) into the console to inspect the object.
Also try document.getElementById("path").outerHTML to see the attributes and children.
Or just document.getElementById("path") and open the tree to view the internals.
This has been asked before but most answers seem to assume that the parent window is also an iframe that can be selected.
I have a DIV in my parent window:
That I want to display if an error happens in an iFrame embedded on the page.
Here is my iFrame javascript I have attempted:
if ( x == "" || y == ""){
parent.document.getElementById("error").style.display ="block";
parent.document.getElementById("error").style.transition ="all 0.5s ease";
parent.document.getElementById("error").style.opacity ="1";
parent.document.getElementById("error_write").innerHTML = "Oops, looks like you've missed an input field. Please ensure both fields are completed in order for the converter to work.";}
This doesn't seem to pull the "error" element from the parent window and display it. This code WORKS if not attempting to access element from another frame.
Please help.
I understand that you've searched this out, but the answer will always be the same .. The reasoning that you cannot do this is security related ... I understand you are trying to do something as benign as "passing an error"
However, Imagine this -- What if you were a malicious person, loading a login page for, say, a bank in an <iframe> on your page -- And you were allowed to pass login variables from the <iframe> to your parent page ... This of course is overly dramatic, however it is the reason most, if not ALL browsers disallow passing data between <iframe> and parent.
My code is as follows:
window.onload = initialise;
function initialise() {
var objPForSubmitMsg = document.createElement('p');
objPForSubmitMsg.setAttribute('class', 'submitmsg');
var arObjForms = document.getElementsByTagName('form');
for (i = 0; i < arObjForms.length; i++) {
var objFormParent = arObjForms[i].parentNode;
alert(objFormParent);
objFormParent.insertBefore(objPForSubmitMsg, arObjForms[i]);
}
} // end initialise().
I checked the function with alerts and it goes through.
When I "view-source" for the page after the function initialise() is done, there are no new elements added.
So my first question would be as per subject: can new elements inserted with javascript be seen with view-source?
If yes, then what is wrong with my code above? Why it doesn't insert new element?
I also tried to call initialise() from a button, but nothing happens then either.
I'm new to javascript so any comments would be appreciated.
EDIT: Thanks everyone. Ok, view-source cannot see it...
Than if I pass my page to php and load it with: $page = file_get_contents("mypage.html"); , if I echo that back with: echo $page; then I guess the newly created elements will not appear there either?
If that is the case, how would you pass the whole thing including the newly js created elements to php?
View Source in the browser shows you the original HTML source of the page - exactly what came from the server before any client side modifications have been made.
As such, it will NOT include any dynamic changes to the page made by javascript.
To see changes that have been made dynamically, use a DOM inspector. There is one built into Safari and Chrome and IE and Firebug is an add-on for Firefox. All will show you the entire DOM hierarchy, live exactly like it currently exists in the browser. In fact, you can even modify the live DOM yourself in the inspector.
Your current code is inserting an empty <p> tag which may not be visible because it's empty. If you put some content into the <p> tag, it successfully inserts one <p> tag into your page. It will only insert one because you only create one and then you try to insert the same tag before each form. You can see what your current code does here: http://jsfiddle.net/jfriend00/3fvbj7re/.
If you want a <p> tag inserted before each form in the page, you'd need to create a separate <p> tag for each insertion like this:
function initialise() {
var arObjForms = document.getElementsByTagName('form');
var objPForSubmitMsg;
for (i = 0; i < arObjForms.length; i++) {
objPForSubmitMsg = document.createElement('p');
objPForSubmitMsg.innerHTML = "hello"; // give tag some content
objPForSubmitMsg.setAttribute('class', 'submitmsg');
var objFormParent = arObjForms[i].parentNode;
objFormParent.insertBefore(objPForSubmitMsg, arObjForms[i]);
}
}
window.onload = initialise;
The Dom elements you add at runtime, were not present when the first time your page was loaded. In other words, it wasn't a part of your original page.
When you view source of your original page, it just shows the HTMl, without executing any JS or CSS, since you only explore HTMl in the source.
Hence, even when you add dynamic html elements in a page, you won't be able to see them when you click view source.
To see those elements, you should use the Developer Console of a browser.
If you want to see the current DOM you should use the code inspector (Developer Tools) or javascript console, not the source, which is what the original response body was.
In Chrome for example go to view->developer->developer tools
I would like to add that just because you can't see it with view-source, doesn't mean you can't access your newly created elements using document.getElementById('el-id') or something similar. Kinda off topic but it's important to note.
I am trying to modify gmail in a greasemonkey script. Using xpather i can get the xpath expression for the part i am trying to hide. But using following snippet i can not get a match. alert function is never called. Can anyone point me to what am i doing wrong?
var allLinks, thisLink;
allLinks = document.evaluate(
"//html/body/div[1]/div/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/div[1]/div[1]",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allLinks.snapshotLength; i++) {
thisLink = allLinks.snapshotItem(i);
alert("found");
}
#Alan Storm
I installed firebug tested the script using console it works but still i can not get it to work under greasemonkey. Greasemonkey still not giving me an alert box. I also tried adding a on load event listener that did not helped either.
First, a general debugging tip, then a stab at your problem.
Remember that Greasemonkey scripts are just javascript, and you can still use all the Javascript tools avaiable to you to debug your problem. Open up gmail, fire up Firebug, and try running your javascript code directly on the command line (click the upward circle arrow to the right of the console line for a bigger typing area).
When I did the above with your javascript snippet, allLinks.snapshotLength was evaluating to 0, indicating that your xpath expression didn't match anything. This is odd, because when I used XPath Checker, it matched the logo.
Digging in a bit deeper, it looks like gmail's main document is a number of iframes, and the iframes contain the actual application elements. Specifically, there's a frame with an ID of "canvas_frame" which contains the actual DOM for the application interface. When I try
canvas = window.frames[document.getElementById('canvas_frame').name].document;
allLinks = canvas.evaluate(
"//html/body/div[1]/div/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/div[1]/div[1]",
canvas,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
I get a response with a length of 1, which may suit your needs better.
Finally, this isn't required, but your xPath expression looks a little fragile. If gmail changes the document structure even slightly (say, with a wrapper div), your program will break. Consider something like this instead.
<!--
all divs on the page that contains an h1 element
that contains the text "Gmail Logo"
-->
//div[contains(./h1,"Gmail Logo")]