Track only iframe history

2019-02-17 18:05发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

use this to access the history of iframe

document.getElementById("test2").contentWindow.history.length


回答4:

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



回答5:

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);


回答6:

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