How can I manipulate using JavaScript (JQuery) a site, not in my server, that I loaded in a frame?
I'm afraid you can't. The Same Origin Policy prevents it.
The same origin policy prevents a document or script loaded from one origin from getting or setting properties of a document from another origin. This policy dates all the way back to Netscape Navigator 2.0.
the only conceivable workaround is to fetch the page through a proxy on your own web server, and do the JavaScript operations on that. This, though, will destroy any relative links on the page, and is therefore usually not a workable approach without a lot of work (fixing relative links, etc.)
Related
I have a website that have a foreign iframe. There are multiple third party scripts that run inside this foreign iframe.
I know that if I will prefetch these scripts from the main window - the iframe will need to reload these sources (as the prefetch was done in a different domain).
What can be the reason that if I add dns-prefetch or preconnect resource hints for the third party scripts in the main window, the performance of loading these scripts in the iframe will be improved? Is this just because I warm-up the scripts?
Some browsers implement a double-keyed HTTP Cache for privacy reasons to prevent tracking. This means if domain1 loads jQuery from a CDN and then domain2 loads the same jQuery resource from the same domain it will be downloaded again rather than reusing the same copy from the HTTP cache.
Safari has done this for a while and Chrome have recently stated they will do the same.
This means you can’t prefetch or preload resources and scripts in foreign domain iframes as you state.
dns-prefetch and preconnect have no such privacy implications (for now - see Andy's answer below for potential upcoming changes for preconnect). so they can be used to improve performance in iframes by front loading some of the work to get these scripts (though it should be noted that browsers may not always use the same connection depending on the browser which may impact use of preconnect).
It's likely that connection pools are also going to become double keyed too –https://github.com/whatwg/fetch/issues/917
In this scenario dns-prefetch will be ok, but a preconnect from the top frame origin for resources referenced in the iframe won't as top frame origin will be different to the iframe origin
Contents of the iframe should still be able to make their own preconnects though – using either link element or HTTP header
(Added as new answer as comments can't have line breaks)
I need to incorporate in my web application some content from an external dynamic web page on which I have no control.
Then I need to filter some of the content of this page or to hide it for presenting only the relevant part that is interesting for my use.
I need also that the scripts on the external page are still working on the source site of the loaded content without cross-site protection.
Is all that possible? How can I do it? Any code example, please?
I suppose that this can be made with JS on client side .
I work on back side and these themes are quite extraneous to me, please don't blame me.
No, it is not possible.
Browser same-origin policy is designed to prevent malicious websites from doing evil.
Same-origin Policy restricts JavaScript network access to prevent evil.
Same-origin Policy also restricts script API Access to prevent evil.
From the Docs:
JavaScript APIs like iframe.contentWindow, window.parent, window.open, and window.opener allow documents to directly reference each other. When two documents do not have the same origin, these references provide very limited access to Window and Location objects.
To communicate between documents from different origins, use window.postMessage.
— MDN Web Security Reference - Cross-origin script API access
One can not use <iframe> elements as a way to "avoid cross site problems". The Same Origin Policy was created to protect users from evil web pages.
I want to get the XPATH of an element on a website (my own domain), which I got it using JavaScript code as mentioned in this answer.
Now what I want to click on button which will open a url (cross domain) window and when user click on an element on that window it's XPATH is captured.
I tried doing the same using iframe with no luck.
Now my question is there a way to get the XPATH of an element of another website/ Cross domain?
Sorry this is not possible without cooperation from the other (x-domain) site. Browsers are designed not to allow access to the DOM of x-domain documents (iframe included) for security reasons.
If you had cooperation from the other site, they could load your javascript file and then use postmessage to pass the xpath to the original page.
Other options would be to create a bookmarklet users could use on the other page, or a browser extension (Chrome and FF are pretty easy to develop for)... depends on your use case.
From your comments, I've gathered that you want to capture information from another website that doesn't have Access-Control-Allow-Origin headers that include your domain (e.g. the other site does not have CORS enabled). This is not possible to do cross-domain and client-side due to the Same-Origin Policy implemented in most modern browsers. The Same-Origin Policy prevents any resources on your site from interacting with resources on any other site (unless the other site explicitly shares them with your site using the Access-Control-Allow-Origin HTTP header).
If you want to get information about another site from your site, there is no way around using server-side code. A simple solution would be to implement a server-side proxy that re-serves off-site pages from your own origin, so the Same-Origin Policy will not be violated.
You may get the data using jQuery's load function, and append it to your page.
From there, the DOM nodes from your external page should be accessible for your processing.
$('#where-you-want').load('//example.com body', function() {
console.log($('#where-you-want'))
// process the DOM node under `#where-you-want` here with XPath.
})
You can see this in action here: http://jsfiddle.net/xsvkdugo/
P.S.: this assumes you are working with a CORS-enabled site.
We have application hosted "xyz:8080/rootapp" and cometd services hosted on "xyz:9090/cometed". The JavaScript loaded from cometd server needs to access the DOM/JavaScripts loaded from (xyz:8080), the browser's same origin policy is not allowing it.
To overcome it we set 'document.domain' as "xyz" eliminating port. This solution is working well but this is becoming problem to all the iframes loaded by "xyz:8080" and I need to change each and every iframe to use domain as "xyz".
Can someone provide me hints to solve this problem without changing each and every iframe?
Do we have any http header to set domain?
You can use CORS to specify an exception to same origin, this will work in any relatively modern browser.
This page has a fairly good intro and a list of compatible browsers.
The short version is put an Access-Control-Allow-Origin header into the responses from xyz:8080 that contains either xyz:9090 or * (for unrestricted access).
I have an environment that doesn't allow server side scripting really (it is extremely difficult to get a script "installed" on the server). I tried using an iframe to violate javascript's same origin poilcy; however, that didn't work. Are there any other workarounds I am not aware of?
Thanks!
As David Dorward mentioned, JSON-P is the simplest and fastest; however, there is another trick, specifically using two iframes.
Two get around this issue without using JSONP, you can do the following. This technique assumes that you have some sort of development access to the parent page.
There are three pages on two domains/sites.
Parent page
Content page
Cross-domain communication page (aka "xdcomm")
Pages the parent and xdcomm pages are hosted on the same domain, the content page is hosted on any other domain. The content page is embedded as an iframe in the parent page and the xdcomm page is embedded as a hidden iframe in the content page.
The xdcomm page contains a very simple script that detects GET parameters in the query string, parses that string for method and args variables (where args is a JSON encoded string), and then executes the specified method with the specified arguments in the parent page. An example can be seen here (view source).
Even though JavaScript's Same Origin Policy restricts code on one domain from accessing that of another, it doesn't matter if domains are nested within each other (domain A, nested within domain B, nested within domain A).
So, in a nutshell, the content page sends messages to the parent page via the xdcomm page by changing the source of the iframe to something like http://domaina.com/xdcomm.html?src=foo&args=[1,2,3,4]. This would be equivalent to executing foo(1,2,3,4) in the parent page.
Also, know that there are already libraries that help you with this, such as easyxdm. What I've explained here is the basis of one of the techniques that they use, and while it might not be as fancy, it is certainly a fully functioning and lightweight implementation.
Hopefully not, as it would be a security hole! :)
But if both your sites are subdomains on the same domain, maybe document.domain can help.