监听浏览器后退事件,使其转向指定URL,控制某些页面不能返回

(一)开发过程中经常遇到这种情况:页面不允许返回到上一页面或者需要转到指定页面,这时候我们就需要监听到浏览器后退事件,从而将它的浏览历史记录删除,然后转向你指定的URL。 具体执行过程如下:

[javascript]  view plain  copy
  1. $(function(){  
  2. //清空浏览器历史记录  
  3. pushHistory();  
  4. //监听浏览器后退事件  
  5. window.addEventListener("popstate",  
  6.     function(e) {  
  7.     //转向指定的URL  
  8.     location.href=url;  
  9.     }, false);  
  10.     //清空浏览器历史记录  
  11.  function pushHistory() {  
  12.         var url = "#";  
  13.         var state = {  
  14.             title: "title",  
  15.             url: "#"  
  16.         };  
  17.         window.history.pushState(state, "title""#");  
  18.     }  
  19. });  
注:这种方法有种缺陷,你将后退事件强制转到URL,如果你连续点击物理返回时会出现这两个页面之间来回跳,已经不是正常的返回了。如果想要返回正常,则需要在之前的n个页面都进行强制跳转,页面多的时候是不可行的。

(二)最近遇到了微信浏览器的后退事件处理,转到指定的URL上述方法就可以实现,但是如果需要监控到返回事件时关闭微信浏览器,因为微信有着自己的JS-SDK,所以需引入微信的js-sdk,传统js:window.close(); 在微信浏览器中不起作用。步骤如下(Java):

引入参考公众号官网:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

1、后台代码:将微信公众号相关参数传到前台

[java]  view plain  copy
  1. /** 
  2. * <b>描述:</b>  
  3. * @param model 
  4. * @param url 当前URL,必须保证一致 
  5. * <br><b>Author:</b> 
  6. * <br><b>Date:</b> 2017年7月25日 下午4:04:20 
  7. */  
  8. public void weixinJS(Model model,String url){  
  9.     WechatInformation wci = wechatInformationService.load();  
  10.     String appId = wci.getAppid();  
  11.     String jsapi_ticket = wci.getJsapi();  
  12.     String noncestr = UUID.randomUUID().toString();  
  13.     String timestamp = Long.toString(System.currentTimeMillis() / 1000);  
  14.     model.addAttribute("appId", appId);  
  15.     model.addAttribute("jsapi_ticket", jsapi_ticket);  
  16.     model.addAttribute("noncestr", noncestr);  
  17.     model.addAttribute("timestamp", timestamp);  
  18.     model.addAttribute("url", url);  
  19.     String signature;  
  20.     try {  
  21.         signature = getSignature(jsapi_ticket,url,noncestr,timestamp);  
  22.         model.addAttribute("signature", signature);  
  23.     } catch (IOException e) {  
  24.         // TODO Auto-generated catch block  
  25.         e.printStackTrace();  
  26.     } catch (AesException e) {  
  27.         // TODO Auto-generated catch block  
  28.         e.printStackTrace();  
  29.     }  
  30. }  
  31. /** 
  32. * <b>描述:</b> JS-SDK使用权限签名 
  33. * @return  
  34. * <br><b>Author:</b> 
  35. * <br><b>Date:</b> 2017年6月5日 下午4:30:23 
  36.  * @throws AesException  
  37.  * @throws IOException  
  38. */  
  39. public String getSignature(String jsapi_ticket,String url,String noncestr,String timestamp) throws IOException, AesException{  
  40.     String s = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url;  
  41.     String signature = getSha1(s);  
  42.     return signature;  
  43. }  
  44. public static String getSha1(String str) {  
  45.     if (str == null || str.length() == 0) {  
  46.         return null;  
  47.     }  
  48.     char hexDigits[] = { '0''1''2''3''4''5''6''7''8''9''a''b''c''d''e''f' };  
  49.     try {  
  50.         MessageDigest mdTemp = MessageDigest.getInstance("SHA1");  
  51.         mdTemp.update(str.getBytes("UTF-8"));  
  52.   
  53.         byte[] md = mdTemp.digest();  
  54.         int j = md.length;  
  55.         char buf[] = new char[j * 2];  
  56.         int k = 0;  
  57.         for (int i = 0; i < j; i++) {  
  58.             byte byte0 = md[i];  
  59.             buf[k++] = hexDigits[byte0 >>> 4 & 0xf];  
  60.             buf[k++] = hexDigits[byte0 & 0xf];  
  61.         }  
  62.         return new String(buf);  
  63.     } catch (Exception e) {  
  64.         // TODO: handle exception  
  65.         return null;  
  66.     }  
  67. }  


2、jsp页面操作

(1)引入js文件:<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

(2)

[javascript]  view plain  copy
  1. $(function(){  
  2.         wx.config({  
  3.             debug: false// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。  
  4.             appId: '${appId}'// 必填,公众号的唯一标识  
  5.             timestamp: '${timestamp}'// 必填,生成签名的时间戳  
  6.             nonceStr: '${noncestr}'// 必填,生成签名的随机串  
  7.             signature: '${signature}',// 必填,签名,见附录1  
  8.             jsApiList: ['closeWindow'// 必填,需要使用的JS接口列表,所有JS接口列表见附录2  
  9.         });  
  10.         pushHistory();  
  11.         window.addEventListener("popstate",  
  12.         function(e) {  
  13.             wx.closeWindow();  
  14.         },false);  
  15.         function pushHistory() {  
  16.             var url = "#";  
  17.             var state = {  
  18.                 title: "title",  
  19.                 url: "#"  
  20.             };  
  21.             window.history.pushState(state, "title""#");  
  22.         }  
  23.     })  
综上,就可以在返回的时候关闭微信浏览器。

注:上述(一)(二)都存在一个问题,在页面加载完毕之后,点击物理返回键,效果是成功的;但是当页面未加载完,物理点击的话js未被触发,就会按history中的记录来回跳转。

(三)要解决上述问题,归根结底是要让不想返回的页面,不要保存到history。这样跳转就不会存在上述问题。

纠结两天找到的解决方案:大致思路就是说将要不想返回的页面(以下简称A.jsp)的URL进行替换,替换成下一个跳转页面B.jsp的URL,当触发跳转事件时reload即可,这样history里头存放的是B.jsp的URL,浏览器history中没有存放,当然返回的时候就不会返回的A.jsp喽。具体如下:

[javascript]  view plain  copy
  1. var replaceUrl;    
  2.         function pushHistory(replaceUrl) {    
  3.             var state = {    
  4.                 title: "title",    
  5.                 url: replaceUrl    
  6.             };    
  7.             window.history.replaceState(state, "title",replaceUrl);    
  8.         }    
  9.      //当点击B.jsp跳转时    
  10.     $("#btn").click(){    
  11.         pushHistory("../"+url);//你要跳转的URL    
  12.         location.reload();    
  13.     }  

注:这个replaceUrl必须是同域,跨域是不允许的

[java]  view plain  copy
  1.   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值