asp.net与h5兼容_背后的ASP.NET代码与Android浏览器中的back()不兼容

asp.net与h5兼容

User

用户

art_snob encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.3.3) tends to ignore the no-cache HTTP headers, and decides at any rate to avoid page reload. This causes severe problems with ASP.NET, which relies on synchronization of code-behind (e.g. a.aspx.vb) with the Web page (a.aspx). art_snob在其移动网站上遇到了Android Web浏览器的奇怪行为。 花了一段时间才找到真正的原因。 碰巧的是,Android Web浏览器(至少在OS 2.3.3版之前)趋向于忽略无缓存的HTTP标头,并尽一切可能避免页面重新加载。 这会导致ASP.NET出现严重问题,这依赖于后台代码(egaaspx.vb)与Web页面(a.aspx)的同步。

Here is a stripped-down example:

这是一个简化的示例:

a.aspx

一个.aspx

<%@ 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 一个.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
ServerButton and the ServerButtonClientButton produce the same result: ClientButton产生相同的结果:

b.html

b.html

<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>
b.html display b.html再次显示 a.aspx again and let you repeat the process. Except a.aspx ,让您重复该过程。 除了“ goback button and the Android browser. 返回”按钮和Android浏览器。

If you start at a.aspx and then click goback, or the system Back button, you will be still able to use the  ClientButton, but the ServerButton will not work at all. Under the hood it will get an ASP.NET exception:

如果从a.aspx开始,然后单击goback或系统的“后退”按钮,您仍然可以使用ClientButton ,但ServerButton根本无法使用。 在幕后,它将得到一个ASP.NET异常:

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 will use an XMLHttpRequest to verify that the copy of the page is not coming from local cache, but is fresh from the server. This way, we can guarantee that code behind will be live.

我将使用XMLHttpRequest来验证页面的副本不是来自本地缓存,而是来自服务器。 这样,我们可以保证后面的代码是实时的。

Here is the Page_Load procedure in a.aspx.vb:

这是a.aspx.vb中Page_Load过程:

    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
a.aspx): 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>
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.

We reload the page by force, and use location.replace() to replace the unhealthy page in the browser history.

我们强制重新加载页面,并使用

Actually, you could choose to do this without using the Session object. Simply generate the server time on the fly in response to the request. Unfortunately, this approach is less robust: you must leave a couple of seconds "freedom" because the server may be too busy between the two requests, and the client may decide to press Back button really quickly.

实际上,您可以选择不使用Session对象来执行此操作。 只需响应请求即可即时生成服务器时间。 不幸的是,这种方法不那么健壮:您必须离开几秒钟的“自由”时间,因为服务器在两个请求之间可能太忙了,并且客户端可能决定很快地按“后退”按钮。

翻译自: https://www.experts-exchange.com/articles/6170/ASP-NET-code-behind-incompatible-with-back-in-Android-browser.html

asp.net与h5兼容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值