Friday, May 25, 2012

Inconsistent behavior of the Back button across different web browsers

A simple scenario of three web pages. The first one, A, allows the user to redirect to the second, B:

<html>
<body>
page A <br/>
<a href="b.html">go to B</a>
</body>
</html>

The second one does something but ultimately it redirects to the last one, C:

<html>
<body>
page B 
<script>
  window.onload = function() { document.location = 'c.html' }
</script>
</body>
</html>

The last one shows a message to the user:

<html>
<body>
page C 
</body>
</html>

Now, open your web browser, navigate to the A page and click the link. You will be redirected to B and from there automatically redirected to C.

Now, try to answer a question: what happens when you click the Back button in your browser on C page?

Well, IE will take you back to B. Opera, Firefox and Chrome, however, treat the B page as a “redirect” page and skip it when you click Back. Clicking Back on C takes you to A then!

This inconsistent behavior of different browsers can be very troublesome! I was not able to find any clear information on this, the only Stackoverflow post seem to mention this issue but with no clear explanation.

Suppose A is a page of your web application, B is a signoff page and C is a relogin page. Suppose now that the user clicks the Back button. Guess what happens on Opera, Firefox and Chrome?

The user is taken to the application page, A! Back button skips the signoff page! And if there is no caching information in HTTP headers in A, the A page will be read from the disk cache, instead of from the server. Which, in other words, means that user will be able to see the page from his application, even though he has just signed off from the application!

How to prevent this? It seems that registering the redirect script in a setTimeout call does the trick. If you also add another script which tries to go one page forward, the behavior is just as one could expect:

<html>
<body>
page B 
<script>
   1: window.onload = function() { document.location = 'c.html' }
</script>
<!-- replace the redirect script !-->
<!-- go forward when possible !-->
<script>
   1: window.onload = function() { setTimeout( "location.href = 'c.html'", 10 ) }
</script>
<script>
   1:  
   2:   window.onunload = function(){};
   3:   window.history.navigationMode = "compatible";
   4:   window.history.go(1);
</script>
</body>
</html>

This solves the problem. Clicking Back in IE, Opera, Firefox and Chrome takes you to B but from there the last script automatically takes you to C.

What this is all about? Well, it seems that the exact problem arises if you use the ADFS2 to signin your users. The A is your application page, B is ADFS2 SignOut.aspx and C is ADFS2 FormsSignIn.aspx.

In a next entry I will show how to address this issue in ADFS2.

No comments: