I have the following HTML markup (don't ask....)
- document //main site
- <iframe> //my site
- <iframe> //site within my site
- <frame>
- <a onclick="JavaScript:parent.parent.location.href='http://bla.com;return false;'">
Basically, main site is calling my site in an iframe. I, in turn, also have an iframe on my site where I'm calling 3rd site. The third site has a frameset with a frame in it that has a link. When clicking on this link, it has to change the url of my site. My site and my child site are on the same domain. When I'm running my site as "stand-alone" (not in iframe) the above code works fine in all browsers.
Once I open my site in an iframe of the main site, it looks like the above code is trying to change the source of the main site. In FireFox I get a console message "Access to property denied". In IE it opens up a new window with my site not in the main site anymore.
What is the correct JavaScript to change the #src attribute on my site when I'm within an iframe?
You are banging your head against the wall that is the same origin policy here. This is XSS country and strictly forbidden, no way around it, unless both domains agree to talk together.
You can read more about cross domain communication using iframes, but again, unless the different domain agree to talk together, you are out of luck.
Although this might seem frustrating, be glad of this rule next time you use homebanking ;)
Can you try something like this
<document> //main site
<iframe id="my_iframe"> //your site
<iframe> //site within your site
<frame>
<a onclick="JavaScript:Top.document.getElementById('my_iframe').location.href='http://bla.com;return false;'">
Top refers to the main window, and then getElementById('my_iframe') will give you your iframe element.
I believe that you're trying to do communication between different pages.
You may take a look this API: HTML5 Cross Document Messaging
Basically, if you want to tell the parent iframe to navigate to a certain url, you can do this:
In the site within my site html:
// onclick of your anchor, post message (an event) with an expected origin
window.postMessage("http://bla.com", "www.sitewithinmysite.com");
In my site html:
// listen to the event "message"
window.addEventListener("message", messageHandler, true);
function messageHandler(e) {
// only recognize message from this origin
if (e.origin === "www.sitewithinmysite.com") {
// then you can navigate your page with the link passed in
window.location = e.data;
}
}
You might want to have the pages communicate using AJAX. Have the site that needs to change its URL listen by long polling to to a node.js server.
Related
I am experimenting with making a website where I have two iframes with other webpages side by side, and would only like to show a certain part of these websites.
Trying to edit the innerHTML of these websites throws errors regarding cross-page security problems.
How can I run Javascript inside these iFrames in a safe manner? If this is not possible, is there a good atlernative for iFrames where I can have to websites side-by-side?
It's not important for me to be able to edit both iFrames, only one of them need to be editable.
An iframe is just a 'hole' in your page that displays another web page inside of it. The contents of the iframe are not in any shape or form part of your parent page.
If your iframe is loaded from the same domain as your parent, then you can access the DOM of the document in the iframe from the parent.
Considering the iframe is from the same domain, Try using the below code and see if it works. The below code will add CSS changes to the iframe. If this works for you, then you can run javascript as well.
<script>
var iframe = document.getElementById("frame1");
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .lt{display:none;} </style>"));
});
</script>
If you are getting "permission denied type errors.", I think what you are doing is subject to the same-origin policy. This should be the reason why you are getting permission denied type errors.
Here you can check the possible solutions.
Unable to access iframe content (same-origin policy)
I want to redirect my browser to another website and then click on a action button on that website. I think i should add some time delay in between these two tasks. The code i have written do only one event at a time.
window.location.href = "http://www.google.com";
var delayInMilliseconds = 2000;
setTimeout(function() {
document.getElementById('action-button').dispatchEvent(new MouseEvent("click"));
}, delayInMilliseconds);
It's forbidden to do this for security reasons.
In computing, the same-origin policy is an important concept in the
web application security model. 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. An
origin is defined as a combination of URI scheme, host name, and port
number. 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.
Source
It is not possible in this manner.
First you change the url of the page which will stop the rest of your JS code from executing. So your timeout will never reach the google page.
Instead implement an <iframe> with the src set to http://www.google.com. Then select the iframe and look for your element in there.
This post will explain how to select the element from an iframe.
Get element from within an iFrame
At the moment you redirect the user with window.location.href any other script won't be executed.
Sort of hack to do what you want is implant script on the second website that will trigger if the user came from a specific URL. Something like that:
var URL = "OLDWEBSITEURL";
var x = window.history.back();
if (x === URL) {
document.getElementById('action-button').dispatchEvent(new MouseEvent("click"));
/* or any other code */
}
Note that if the user open the link on different window/tab or/and disable js it won't work.
I am try to write a simple web based version of the wiki game, which starts with a url and has a goal url that the user must reach only by clicking links in the wikipedia pages. The general idea was to have the starting wikipedia url in an iframe, and within the iframe the user can click links to go to other pages.
The problem is that it seems like there are restrictions on tracking user activity within an iframe unless the contents of the iframe are hosted from the same domain as the web application itself. So if a user clicks on a link within the iframe which leads to another page, I cannot find a way to track the new page that the user has gone to. Even if I could just get the name of the link they clicked on this would be enough. For instance, if the user clicked on a link within the iframe named Europe, I could use PHP to go to a new page and load the new wikipedia iframe dynamically. It would look like the following:
<?php
$article = $_GET["article"];
?>
<iframe id="frame" src="https://en.wikipedia.org/wiki/<?php echo $article ?>"
There just doesn't seem to be an obvious way to track user activity within an iframe. Any suggestions? Also below is a link to a version of the game, which has the same general idea as what I am aiming for. It also appears to use iframes to store the wikipedia pages.
http://cs.mcgill.ca/~rwest/wikispeedia/
For security reasons, if you can't add code to the iframe URL, you can't measure interactions with that page.
However, you could create a proxy that injects some code:
window.postMessage(window.location,'*');
You'll need to rewrite links on the page to refer to your proxy instead of their original targets.
Then on your host page:
window.addEventListener("message", onMessage, false);
function onMessage(event) {
console.log(event.data);
}
It's worth noting that this would effectively let arbitrary code run on a URL belonging to you. That probably presents a security risk.
I have a rather interesting problem. I have a parent page that will create a modal jquery dialog with an iframe contained within the dialog. The iframe will be populated with content from a 3rd party domain. My issue is that I need to create some dialog level javascript that can detect if the content of the iframe loaded successfully and if it hasn't within a 5 second time frame, then to close the dialog and return the user to the parent page.
I have researched numerous solutions and only two are of any true value.
Get the remote site to include a javascript line of document.domain = 'our-domain.com'.
Use a URL Fragment hack, but again I would need the request that the remote site
able to modify the URL by appending '#some_value' to the end of the URL and my dialog window would have to poll the URL until it either sees it or times out.
Are these honestly the only options I have to work with? Is there not a simpler way to just detect this?
I have been researching if there's a way to poll for http response errors, but this still remains confined to the same restrictions.
Any help would be immensely appreciated.
Thanks
The easiest way (if you can get code added to the external sites) is to have them add an invisible iframe pointing to a special html file on your domain. This could then use parent.parent.foo() to notify the original window about the load event.
Listening for the "load" event will only tell you if the window loaded, not what was loaded or if the document is ready for interaction.
Nicholas Zakas has an article about detecting if an iframe loaded: http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/. Basically you have this code snippet:
var iframe = document.createElement("iframe");
iframe.src = "simpleinner.htm";
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
alert("Local iframe is now loaded.");
});
} else {
iframe.onload = function(){
alert("Local iframe is now loaded.");
};
}
document.body.appendChild(iframe);
I haven't tested it, but I'm pretty sure jQuery should be able to handle it by doing something like $("#iframe").load(function () { alert("Local iframe is now loaded."); });
You could try using postMessage for communication between frames.
This will require the remote site to include some specific JavaScript to post a message to the parent document when it has finished loading.
It's possible to do this with an onload handler on the iframe itself. Unfortunately (surprise!) IE makes it difficult. The only way I could get this to work was to compose HTML for the iframe, then append it to the document with innerHTML. Then I have to poll to see when the iframe appears in the DOM, which varies depending on if the page is loading. Here's a link to the source: http://svn.openlaszlo.org/openlaszlo/trunk/lps/includes/source/iframemanager.js
See create(), __finishCreate() and gotload(). Feel free to take a copy of this and use it yourself!
Regards,
Max Carlson
OpenLaszlo.org
This is how I detected the loading of a Cross-Domain Iframe,
Set a unique id for the iframe ( U may use any sort of identifier, it doesn't matter )
<iframe id="crossDomainIframe" src=""> </iframe>
Set window event listener:
document.getElementById("crossDomainIframe").addEventListener('load',
function actionToPerform(){
//Do your onLoad actions here
}
)
In any case you will need some sort of cooperation from the other domain's server, as you are trying to abuse the Same Origin Policy (SOP)
The first solution document.domain=... won't work if domains are different. It works only for subdomains and ports, as described in the link above.
The only option that allows cross domain communication without polling is JSONP or script injection with a JS function callback. This method is available in all Google APIs and works well.
We've explained on our blog a way to sandbox those calls in an iframe to secure them. While postMessage is better now, the window.name hack has the advantage of working on old browsers.
Ironically, SOP does not prevent you to POST anything to another domain. But you won't be able to read the response.
I have a 'toolbar' that displays some code on the top of the window, and then I load an iframe with an external site. I realize that I can't get the active link the user is on because it would be a violation of same origin policy.
Is there any way (using greasemonkey maybe?) that I could get the active url of the external iframe?
I need to do this for demo purposes, not for anything practical. (I realize the real solution would be to process the entire page through my own server)
Thanks!
I'll post a workaround that I wrote:
If you install greasemonkey, write a script does (roughly) something like this:
current_link = document.location.href;
if(current_link !== 'http://my_local_site')
{
GM_setVal("link", current_link); }
Have greasemonkey run this script on your iframe's URL and on your local site and on your iframe's site.
GM will save to its internal memory the link. If you don't trigger the IF statement, you're probably reading the script from your local site, ergo you need to:
unsafeWindow.urlVal = GM_getVal("link");
All you need to do now is to get both the local frame and the iframe to run the script every time a page is navigated on the iframe.
You can get this done on your local frame by a) timing it b) using some type of event trigger.
Best of luck!