5

I have a page which contains an iframe and I want to track the history of the iframe only. I tried to use the history object like this:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <script type="text/javascript">
        function checkFrameHistory() {
            alert(window.frames["test2"].history.length);
        }

        function checkThisHistory() {
            alert(history.length);
        }
        </script>
    </head>
    <body>

        <iframe name="test2" src="test2.html"></iframe>

        <div>
            <input type="button" onclick="checkFrameHistory()" value="Frame history"/>
            <input type="button" onclick="checkThisHistory()" value="This history"/>
        </div>

    </body>
</html>

test2.html

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <script type="text/javascript">
        function checkMyHistory() {
            alert(history.length);
        }
        </script>
    </head>
    <body>
    <div>
        Test2
    </div>

    <div>
        <input type="button" onclick="checkMyHistory()" value="My history"/>
    </div>

    </body>
</html>

but it actually gave me the history including the parent window.

For instance, I went to another site in the main window and came back to my iframe test site. Both window.frames["test2"].history.length and history.length still gave me the same count by increasing the length by 2.

Did I do it wrong? Is there a way to track only the iframe history?

evanwong
  • 4,696
  • 3
  • 28
  • 43

6 Answers6

5

Chrome manages history on window base; not on separate frames. This behaviour is probably the cause of your problem.

Dont know if its default behaviour for all browsers btw.

Edit: You have to maintain your navigationhistory server side. Keeping an array on the mainwindow, as stated in another answer, doesnt work when you also navigate with the parent window.

Ruben-J
  • 2,625
  • 11
  • 32
4

There is an easy way to do this, provided of course that the iframe content is the same domain.

From the parent you bind to the beforeUnload or the load event of the iframe's window object. In the event's callback handler you simply do something along the lines of locations.push(getElementById("iframe").contentWindow.location.href) where locations is of course a previously defined array in the parent scope.

David Mulder
  • 24,033
  • 8
  • 45
  • 104
3

use this to access the history of iframe

document.getElementById("test2").contentWindow.history.length
Raab
  • 31,764
  • 4
  • 47
  • 63
1

It's unlikely you will be able to access any objects associated with the frame because of the same-origin policy.

Have you tried setting the domains to be equal on the page itself and the iframe? e.g.

//somewhere on your page in a script tag
document.domain = "your-top-level-domain.com";

this should signal to the browser that the pages trust each other and should be given access to their internal state

WickyNilliams
  • 4,876
  • 1
  • 26
  • 42
  • um... currently those html pages are localhost and should be on same domain already... it seems like i am able to access the history in the iframe like: `window.frames["test2"].history`... at least i don't get any error... it is just that the frame's history object seems to be including the original page history instead of just referring to the iframe history only... – evanwong May 29 '12 at 15:31
  • oh i see my mistake. Right, try changing your code to access the iframe as such `window.frames["test2"].contentWindow.history`. The `contentWindow` is the important part – WickyNilliams May 29 '12 at 15:40
0

If the frame contains contentWindow, you can use frame.contentWindow.history.

But not all browsers support this property. If not, the frame's location should be stored in some variables. Bind event handler on your frame onload event like below(using jquery)

var frameHistory = [];
$(document).ready(function(){
    var frame = window.frames["test2"];
    $.bind(frame, "onload", function(){ //store location when frame loads
        frameHistory.push(frame.window.location.href);
    }
});

And in your button click event handler:

alert(frameHistory.length);
Chris Li
  • 3,648
  • 2
  • 25
  • 31
0

ITS POSSIBLE to beat SOP as long as you have access to both domains. You can use a helper IFRAME to pass onchange events from the BODY.

This post should be extremely helpful: Resizing an iframe based on content

Community
  • 1
  • 1
Dan Kanze
  • 18,097
  • 28
  • 77
  • 133