Access iframe node given element node inside iframe using Javascript only - javascript

Say I'm given an HTML element node, such as a
<div id = "content"></div>
and that's contained in an iframe. It's passed in to me as a node. I want to be able to get the iframe node that the element's in -- there's no specific id and I want to be able to access it just from the element node. I've tried
elNode.window
and
elNode.parent
But obviously that gives me undefined. I'm also passed in the current window, but trying
curWindow.parent
just passes me in the window, so that was led to no avail. I really just want to get the iframe from the element node. If anyone has any pointers, that's much appreciated.

this issue is due to the same-origin policy: the browser won’t allow the original script to inspect the contents of the cross-origin document. more details about sop https://en.wikipedia.org/wiki/Same-origin_policy. Generally, there are following ways to solves this issue:
using element has never really been subject to the same-origin policy: it will download and execute any script, regardless of origin.
cross-document messaging,allows a script from one document to pass textual messages to a script in another document, regardless of the script origins. Calling the postMessage() method on a Window object results in the asynchronous delivery of a message event (you can handle it with an onmessage event handler function) to the document in that window.
Cross-Origin Resource Sharing https://www.w3.org/TR/cors/ : This draft standard extends HTTP with a new Origin: request header and a new Access-Control- Allow-Origin response header. It allows servers to use a header to explicitly list origins that may request a file or to use a wildcard and allow a file to be requested by any site.
To support multi domain websites of this sort, you can use the domain property of the Document object . But, the domain value must have at least one dot in it; you cannot set it to “com” or any other top-level domain. for example ecar.car.com, pcar.car.com. you can set the domain to car.com.
hope this can give you a kind of help

Related

Will the browser fetch new resources when you change the DOM with javascript?

I have the following in the HTML body of a page:
<aside id="ADVERT">
<img src='https://www.blackstone.com/images/default-source/assets/logos/blackstone-logo.png'>
</aside>
Later in the page, there is a button that, when clicked, switches the img with another. Here is the button code:
<button onclick="switchadvert();">Switch Logo</button>
This switchadvert Javascript function is simplicity itself, just one line, using the innerHTML property:
function switchadvert()
{ document.getElementById("ADVERT").innerHTML = "<img src='http://www.redstone.com/gfx/logo.png'>";
}
This all appears to work. When I click the button, the logo changes from the Blackstone Group's logo to Redstone's logo.
My question is how does this work, and why does it work?
HOW:
Apparently, as soon as I update the DOM with this new innerHTML, the browser realizes this part of the page requires a resource it does not have (the redstone logo) and goes and fetches it? Long after the page has loaded?
WHY:
I thought that even if I went to the trouble of doing an AJAX call, to an XMLHttpRequest object, I was not allowed to go get resources from another site after the page has loaded. But here it is doing it without any calls! Doesn't this open the door for cross-site scripting abuse?
For the <img> question, and how does the browser know it has to fetch new resources, that's simply what does the HTMLImageElement when its src property is set.
It doesn't matter when this happens, and the element doesn't even have to be appended in the document; when you set this src, its fetch algorithm will kick in.
For the cross-origin question, this neither has no relation with when the request is made. But to clarify an other misconception, cross-domain restrictions are here to avoid scripts being able to access cross-domain data, but you can still very well display cross-domain data in your page. And here, since you didn't set the cross-origin attribute of your <img>, then you won't be able to access the content of this image.
TL;DR:
In today's browsers there should be no treat to XSS by loading an image
When it comes to fetching data there is a rule called CORS that comes into play.
CORS only allows certain methods with a few allowed headers without additional configuration on the server end.
When it comes to images, the browser will fetch (GET) the url, which it allows by CORS and then determine its content type, either by looking at the Content-Type header or some other processes.
Assuming the source is not affected by XSS and if it's a valid image, it will display it and if not throw an error, but the browser will never execute any javascript inside the browser so there is no threat to XSS. You can test this by having an image source set to a javascript file.

JQuery: Select div under iframe with JQuery

I'm trying to select a div used in an iframe, but the select instruction always return an empty object, any idea how to solve this please:
console.log($(this).contents().find('div'));
JSFiddle: https://jsfiddle.net/8jxvry4c/6/
Div is not accessible because it is not part of your DOM but part of iframe which itself consist different DOM for some other place.
In order to get div of iframe, you need to fetch all content of iframe and then find the div you wanted.
Following code can be used to fetch iframe content but it should be within same domain if not it will throws cross domain error
$('iframe').contentWindow.document.body.innerHTML
Or you can use cross-document messaging in Javascript where message is sent to iFrame and iFrame respond accordingly.
Main page
myIframe.contentWindow.postMessage('hello', '*');
iframe
window.onmessage = function(e){
if (e.data == 'hello') {
alert('It works!');
}
};
You can refer this link for more detail.
There are also some plugin available to perform these kinds of task more swiftly.
You can't access to DOM of a different domain because of Same-origin policy
Under the policy, a web browser permits scripts contained in a first
web page to access data in a second web page, but only if both web
pages have the same origin.
This policy prevents a malicious script on one page from obtaining
access to sensitive data on another web page through that page's
Document Object Model.
But you can accomplish this on server side of course performming a GET/POST request. And again you can't perform a GET/POST request from javascript (ajax) unless the other domain have Access-Control-Allow-Origin header.

Autoloading invalid javascript files

I've created a script which autoloads javascript files based on the users location. Like any other loaders, I create a <script> element, set it's src attribute and add it to <head>. I then listen for onload and onreadystatechanged etc. events, then check for the presence of a value exposed by the file. This works.
The problem is, when supplied with an invalid cross origin url "http://fail_on_purpose", my ISP returns HTML (directing the browser to reload with a different address). I can catch this in the onload event, but it's too late. The HTML has already been injected on the page within the <script> tags. This then causes the browser (firefox at least) to issue a SyntaxError exception.
All I can do is remove the offending element from the DOM. But, I don't know if this is going to cause problems in other browsers, so I would prefer to not have the error at all.
What is the best way to check for a valid javascript file then inject it into the page?
Update:
Issuing a HEAD or GET request to check if the file exists/is valid, doesn't work due to the "Cross Origin" protection in the browser. I don't have access to the CDN, so that is an unfixable problem.
You could send a HEAD request and parse response headers to see if the page returns successfully, i.e. not with redirection, client error or server error response code. Any decently implemented server should set correct response code.
Ideally, you'd also check content-type to include application/javascript, if the server is set up to set it correctly.
If this matches, you know that the script exists, so you can then proceed with loading it the same as you do now.
Alternatively, you already get these headers with GET request, so you could do all that with a single request. But with incorrect request, you'll be waiting for all the payload before determining it's incorrect, which will take up more time and waste data transfer. The latter is something worth considering if you're expecting mobile users, you wouldn't want to waste data plans like that.
As Sumit suggests, you might load the script via an Ajax request, then check it somehow (e.g. because you know that it contains a particular string).
On success, just proceed as you did - append a <script> tag to the head or body element with the "src" attribute set. If caching is enabled for the URL, the browser won't do another HTTP request for that.
Using the Ajax-loaded JS code directly (by setting scriptElem.text instead of the "src" attribute) is another option, but not as good, since it is subject to CORS restrictions. See jQuery's DOMEval function, https://code.jquery.com/jquery-3.1.0.js (line 77)
Since you want to load the code from the Google servers, the "src"-attribute version is better.

How to get the parent protocol from within an iFrame using javascript?

I have two CDN domains, one that delivers content over https and the other one through http. And I'm creating a widget (inside an iframe) that could be used in a variety of domains and sometimes in secure pages and sometimes not.
Is there a way to infer using JavaScript the parent's protocol from within the widget's iFrame ?
I figured it out, if I ommit the protocol in the iframe of my widget then it will inherit the protocol of the parent, eg:
In my widget html:
<script>document.write("my protocol is " + document.location.protocol);</script>
The iframe code that points to my widget (to insert into the other sites):
<iframe src="//my-widget.example.com/widget"></iframe>
This requires my-wdiget.example.com/widget to work for both secure and unsecure connections (ie: http://my-widget.example.com/widget and https://my-widget.example.com/widget should both point to the same content) but that's OK because in my situation the only domains I don't have control over are the ones used as CDN.
You can get informations from the main window just using:
window.parent.

Accessing an element outside of iframe

I have a file: 1.html and an iframe inside it.
I want to access an element (lets say myelement) which exists in 1.html (outside of iframe) from the iframe.
How can I do that?
I tried:
top.getElementById("myelement")
top.document.getElementById("myelement")
parent.getElementById("myelement")
parent.document.getElementById("myelement")
but it didn't work!!
Communication between an iframe and parent document is not possible for cross-origin resources. It will only work if the iframe and the containing page are from the same host, port and protocol - e.g. http://example.com:80/1.html and http://example.com:80/2.html
For cross-origin resources, you can make use of window.postMessage to communicate between the two, but this is only useful if the browser supports this method and if you have control over both resources.
Edit - assuming both resources are from the same origin
In the iframe, window.parent refers to the global object of the parent document, not the document object itself. I believe you would need to use parent.document.getElementById
Assuming that same origin policy is not a problem, you can use parent.document to access the elements, and manipulate them.
Demo here, source of outer frame here, source of iframe here.
parent.document Not working
For cross-origin resources, you can make use of window.postMessage to communicate between the two, but this is only useful if the browser supports this method and if you have control over both resources.
Communication between an iframe and parent document is not possible
for cross-origin resources
that is in so many ways wrong, i dont even WANT to know where to begin. Of course cross-domain requests and algorith-exchanges have a long history, it is both well documented and working now, one might start JSON-request or even simple XMLHttp-Requests via JQuery, for example, you can even load whole .js-files AND inject them into your code - injecting code in remote sources will of course need an appropriate interface; one may achieve such a thing via communication with the responsible persons, just ask them nicely and maybe they'll cooperate if your project makes sense and has its use.
To answer the question : accessing whole documents would raise the need for transferring it beforehand - i would recommend XML for that purpose because the DOM-tree and XML are nearly interchangeable. Load the tree via .get (.ajax for remote hosts), append it to this and access it just like you want ... sounds easy and if you got some experience it IS easy. If you ever read "cross-domain" and "not possible" in the same sentence again you might as well ignore the poster - there are many people out there who dont know what they're talking about ;-)

Categories

Resources