<%@ Page Language="VB" CodeFile="a.aspx.vb" Inherits="a" EnableViewStateMac="False" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML xmlns="http://www.w3.org/1999/xhtml">
<HEAD id="Head1" runat="server">
<TITLE>a.aspx</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
</HEAD>
<BODY>
<FORM id="form1" runat="server">
<div id="container">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Button ID="ServerButton" runat="server" OnClick="Button_Click" text="go to b.html on server" /><p />
<asp:Button ID="ClientButton" runat="server" onClientClick="location = 'b.html'" text="go to b.html on client" /><p />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</FORM>
</BODY>
</HTML>
a.aspx.vb
Partial Class a
Inherits Page
Protected Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs) Handles ServerButton.Click
Response.Redirect("b.html", False)
End Sub
End Class
Now, on any known browser, the ServerButton and the ClientButton produce the same result:
<html>
<head>
<title>b.html</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
<input name="goback" onclick="history.back()" type="button" value="go back" /></p>
<input name="gotoA" onclick="location='a.aspx'" type="button" value="go to a.aspx" /></p>
<input name="replaceA" onclick="location.replace('a.aspx')" type="button" value="replace to a.aspx" /></p>
<input name="openA" onclick="window.open('a.aspx', 'top')" type="button" value="open a.aspx" /></p>
</body>
</html>
And on all known browsers, all four buttons in b.html display a.aspx again and let you repeat the process. Except goback button and the Android browser.
E/browser (xxx): Console: Uncaught Sys.WebForms.PageRequestManagerServerErrorException: Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 0 http://xxx/ScriptResource.axd?d=31hrpqnrjCS7Ljksbfakhjr6vQHbaDyxah__zHgcOttSylOBq8Zbq2kxgVMdA3MThu4aquTF9WtwbL8sY19YcnLh9RlqCkMMQlaKeoC5pMVR-tgb3iU8M6inww0QtoQYLpIsOrH70stFuO0SE_LVrEyvT7miOJgBVPvhCD-3ekjwH95jk8pHDxgtqXOa4aGu0&t=2610f696:5
I have explained above what causes this problem. Now our task is to find an easy and reliable plumbing.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim uni = Request.QueryString("getUnique")
If uni = "" Then
HttpContext.Current.Session("QQQ") = Now().toString("ms")
Else
If (HttpContext.Current.Session("QQQ") Is Nothing)
uni = "9999"
Else
uni = HttpContext.Current.Session("QQQ")
End If
Response.Write(uni)
Response.Flush()
End If
End Sub
and here is the client-side javascript (put it somewhere inside a.aspx):
<script>
originalServerTime = <%= HttpContext.Current.Session("QQQ") %>
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
newServerTime=parseInt(request.responseText);
console.log("newServerTime: " + newServerTime + " originalServerTime: " + originalServerTime);
if (newServerTime != originalServerTime) // if not using Session persistence, allow for up to 2 sec delay
{
location.replace(location.href);
}
}
};
var ser = Math.round(Math.random()*1000000); // Anti-caching random number
request.open('GET', location.href + '?' + 'getUnique=' + ser, true);
request.send(null);
</script>
So, we generate a new request, make sure that it is never cached (with random getUnique), and retrieve the value that should be identical to the one embedded with <%= %> when the page was generated. If the values differ, the page has lost its connection to code behind.
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (0)