"返回"按钮的解决方案摸索
2011-11-25 10:40
183 查看
做过网站或WEB系统的,肯定都曾在自己的页面中用过“返回”按钮。我也不例外,在多次的开发中,我曾经思索:这个小小的“返回”按钮,应该以怎样的代码实现比较好。
先说说自己最常使用的,也是最常见最无脑的。如:
有时候,当返回的页面的是一个带分页的页面时,则需要在进入页面时传入分页信息,然后在返回时取出这些值。比如:
用的最多的,无非以上了。
有的时候,再复杂一些,比如一个页面可以从不同的页面跳入,那么,还得再记录哪个页面来的,返回的时候,再判断判断。
再有的时候,A页面跳到B页面,B页面再跳到C页面,这个时候想要连着两次返回到A页面,要写的代码就多了。
那么,这个小小的“返回”按钮有没有什么好的方法去处理呢?
首先我尝试了这样的方法:
曾经在某些页面中用过这样的方法,似乎也没什么问题。但这个方法是有使用范围限制的,通常它适合用在静态页面。另外,当跳转之前页面执行了某个脚本,而这个脚本中alert了一下,此时用这个方法跳转回来的时候,我发现它又alert了一下,这显然不行。
接着我又尝试了这样的方法:
前两个方法写在自定义的页面基类中,并且我约定了系统中总是将分页,查询,排序等参数信息保存在URL中。接着我制作了对应的分页控件,正当我沾沾自喜,以为大功告成的时候,又一个问题出现了。
Request .UrlReferrer .PathAndQuery 这句代码似乎会有失灵的时候。
经过几次尝试,发现问题是这样的:
假设从A页面跳转至B页面,那么A页面的方式如果是以脚本的方式进行跳转的话,那么在B页面调用SaveCurrURL方法是获取不到预期的值的,比如(location.href=。。。。),而在A页面以超链接的方式进行跳转的话,则可以顺利获取到。
这是何故?又怎麽办呢?我们知道,用户点击超链接属于用户主动行为,而脚本触发,则属于被动行为,有时候某些被动行为会因为安全方面的考虑而受到重重阻碍。我们可以以脚本的方式触发超链接元素的onclick事件,确很难模拟用户直接点击超链接的效果(我认为是不能)。
后来我决定退一步,牺牲一下性能,将代码改成Session["prevURL"] = Request.Url.PathAndQuery;
并且为了支持两级的返回,最后的代码是这样的
最终的代码费了我不少心思,为了使session保持小巧,我用了string数组,而不是string list,为了支持两级返回,我将数组的长度设为3,这是有原因的。
它们是这样的使用方式,假设有A\B\C 3个页面,
A可以跳到B,B可以跳到C,C可以返回B,B可以返回A。
那么在A页面,这是一个起点页面,调用SaveCurrURL传入TRUE参数,B和C页面的参数为FALSE,注意C页面也要调用,这属于一个瑕疵。
在B和C的返回按钮中,不论他们是不是从A跳过来的,也不论他们处与第2个页面还是第3个页面,统统调用
Response.Redirect(this.GetCurrURL ());
最后,别忘了在if (!IsPostBack)中调用Save函数.
以上便是我对“返回”功能的小小尝试,只能说支持一定的使用范围,有一定的简化作用和通用的处理方式。当然它没有经过严格的测试,也希望大牛们能提供更好的方案。
URL保存和获取方法都稍微了改了一下。
现在在有返回按钮的页面上这样用:
这样就避免了服务器重定向。提高了性能。
先说说自己最常使用的,也是最常见最无脑的。如:
protected void Back() { Response.Redirect("CurrList.aspx"); }
有时候,当返回的页面的是一个带分页的页面时,则需要在进入页面时传入分页信息,然后在返回时取出这些值。比如:
private void Goback() { string size = Request.QueryString["size"]; string index = Request.QueryString["index"]; Response.Redirect("SellInfoDisplay.aspx?size=" + size + "&index=" + index ); }
用的最多的,无非以上了。
有的时候,再复杂一些,比如一个页面可以从不同的页面跳入,那么,还得再记录哪个页面来的,返回的时候,再判断判断。
再有的时候,A页面跳到B页面,B页面再跳到C页面,这个时候想要连着两次返回到A页面,要写的代码就多了。
那么,这个小小的“返回”按钮有没有什么好的方法去处理呢?
首先我尝试了这样的方法:
history.go(-1);
曾经在某些页面中用过这样的方法,似乎也没什么问题。但这个方法是有使用范围限制的,通常它适合用在静态页面。另外,当跳转之前页面执行了某个脚本,而这个脚本中alert了一下,此时用这个方法跳转回来的时候,我发现它又alert了一下,这显然不行。
接着我又尝试了这样的方法:
protected void SaveCurrURL() { Session["prevURL"] = Request.UrlReferrer.PathAndQuery; } protected string GetCurrURL() { return Session["prevURL"].ToString(); } protected void Back() { Response.Redirect(this.GetCurrURL()); }
前两个方法写在自定义的页面基类中,并且我约定了系统中总是将分页,查询,排序等参数信息保存在URL中。接着我制作了对应的分页控件,正当我沾沾自喜,以为大功告成的时候,又一个问题出现了。
Request .UrlReferrer .PathAndQuery 这句代码似乎会有失灵的时候。
经过几次尝试,发现问题是这样的:
假设从A页面跳转至B页面,那么A页面的方式如果是以脚本的方式进行跳转的话,那么在B页面调用SaveCurrURL方法是获取不到预期的值的,比如(location.href=。。。。),而在A页面以超链接的方式进行跳转的话,则可以顺利获取到。
这是何故?又怎麽办呢?我们知道,用户点击超链接属于用户主动行为,而脚本触发,则属于被动行为,有时候某些被动行为会因为安全方面的考虑而受到重重阻碍。我们可以以脚本的方式触发超链接元素的onclick事件,确很难模拟用户直接点击超链接的效果(我认为是不能)。
后来我决定退一步,牺牲一下性能,将代码改成Session["prevURL"] = Request.Url.PathAndQuery;
并且为了支持两级的返回,最后的代码是这样的
protected void SaveCurrURL(bool first) { if (Session["prevURL"] == null) Session["prevURL"] = new string[3]; string[] urls = (string[])Session["prevURL"]; if (first) { urls[0] = Request.Url.PathAndQuery; urls[1] = null; urls[2] = null; } else { if (urls[1] == null) urls[1] = Request.Url.PathAndQuery; else urls[2] = Request.Url.PathAndQuery; } Session["prevURL"] = urls; } ///<summary> /// 获取上次保存的URL ///</summary> ///<returns></returns> protected string GetCurrURL() { string[] urls = (string[])Session["prevURL"]; for (int i = 2; i >= 0; i--) { if (urls[i] != null) { string url = urls[i-1]; urls[i] = null; urls[i - 1] = null; Session["prevURL"] = urls; return url; } } throw new Exception(""); }
最终的代码费了我不少心思,为了使session保持小巧,我用了string数组,而不是string list,为了支持两级返回,我将数组的长度设为3,这是有原因的。
它们是这样的使用方式,假设有A\B\C 3个页面,
A可以跳到B,B可以跳到C,C可以返回B,B可以返回A。
那么在A页面,这是一个起点页面,调用SaveCurrURL传入TRUE参数,B和C页面的参数为FALSE,注意C页面也要调用,这属于一个瑕疵。
在B和C的返回按钮中,不论他们是不是从A跳过来的,也不论他们处与第2个页面还是第3个页面,统统调用
Response.Redirect(this.GetCurrURL ());
最后,别忘了在if (!IsPostBack)中调用Save函数.
以上便是我对“返回”功能的小小尝试,只能说支持一定的使用范围,有一定的简化作用和通用的处理方式。当然它没有经过严格的测试,也希望大牛们能提供更好的方案。
修改了一下:
有人提出服务器重定向不好,我也觉得,所以又改了一下,不用Button 用HyperLink,当然代码也要修改protected void SaveCurrURL(bool first) { if (Session["prevURL"] == null) Session["prevURL"] = new string[3]; string[] urls = (string[])Session["prevURL"]; if (first) { urls[0] = Request.Url.PathAndQuery; urls[1] = null; urls[2] = null; } else { if (urls[1] == null) urls[1] = Request.Url.PathAndQuery; else if (urls[2] == null) urls[2] = Request.Url.PathAndQuery; else urls[2] = null; } Session["prevURL"] = urls; } ///<summary> /// 获取上次保存的URL ///</summary> ///<returns></returns> protected string GetCurrURL() { string[] urls = (string[])Session["prevURL"]; for (int i = 2; i >= 0; i--) { if (urls[i] != null) { string url = urls[i-1]; Session["prevURL"] = urls; return url; } } throw new Exception(""); }
URL保存和获取方法都稍微了改了一下。
现在在有返回按钮的页面上这样用:
this.SaveCurrURL(false ); lbBack.NavigateUrl = this.GetCurrURL();
这样就避免了服务器重定向。提高了性能。
相关文章推荐
- &quot;返回&quot;按钮的解决方案摸索
- ASP.NET:"返回"按钮的解决方案摸索
- 微信素材上传返回提示 "errcode":41005的原因以及以及解决方案
- 安卓中点击返回,"再点击一次推出程序"代码实现
- 为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?
- ssh 项目中struts2 "input"返回后无法执行Action解决方法
- getPath()返回的路径包含的"20%"(空格)的处理
- MSDN帮助文档 "无法显示该网页" 的问题解决方案(转)
- "ORA-01502: 索引''或这类索引的分区处于不可用状态"的解决方案
- OpenERP-隐藏多对多域弹出列表视图的"新建"按钮(Hide the "Create" button from the popup list view of a many2many field)
- CentOs中从图形界面转到终端用"startx"不能返回图形界面的问题
- 【ARM-Linux开发】"libxml/parser.h: 没有那个文件或目录"解决方案
- 错误信息:"OraOLEDB.Oracle" 返回了消息 "ORA-12154: TNS: 无法解析指定的连接标识符
- 挂载文件系统出现"kernel panic..." 史上最全解决方案
- [Android] 更好的解决 "返回键或取消时自动回调DatePickerDialog的方法onDateSet()" 的问题
- VS 用RasDial结果返回 "检测到一个不正确的结构大小"错误代码632 VS2010 VC6正常,怎解?!
- Jquery mobile 自定义 返回按钮 data-rel="back"
- "分布式事务"解决方案汇总 -- 2PC/TCC/事务消息/1PC
- "分布式事务"解决方案汇总 -- 2PC/TCC/事务消息/1PC
- 有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。