監聽瀏覽器後退事件,使其轉向指定URL,控制某些頁面不能返回
(一)開發過程中經常遇到這種情況:頁面不允許返回到上一頁面或者需要轉到指定頁面,這時候我們就需要監聽到瀏覽器後退事件,從而將它的瀏覽歷史記錄刪除,然後轉向你指定的URL。 具體執行過程如下:
注:這種方法有種缺陷,你將後退事件強制轉到URL,如果你連續點選物理返回時會出現這兩個頁面之間來回跳,已經不是正常的返回了。如果想要返回正常,則需要在之前的n個頁面都進行強制跳轉,頁面多的時候是不可行的。$(function(){ //清空瀏覽器歷史記錄 pushHistory(); //監聽瀏覽器後退事件 window.addEventListener("popstate", function(e) { //轉向指定的URL location.href=url; }, false); //清空瀏覽器歷史記錄 function pushHistory() { var url = "#"; var state = { title: "title", url: "#" }; window.history.pushState(state, "title", "#"); } });
(二)最近遇到了微信瀏覽器的後退事件處理,轉到指定的URL上述方法就可以實現,但是如果需要監控到返回事件時關閉微信瀏覽器,因為微信有著自己的JS-SDK,所以需引入微信的js-sdk,傳統js:window.close(); 在微信瀏覽器中不起作用。步驟如下(Java):
引入參考公眾號官網:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
1、後臺程式碼:將微信公眾號相關引數傳到前臺
/** * <b>描述:</b> * @param model * @param url 當前URL,必須保證一致 * <br><b>Author:</b> * <br><b>Date:</b> 2017年7月25日 下午4:04:20 */ public void weixinJS(Model model,String url){ WechatInformation wci = wechatInformationService.load(); String appId = wci.getAppid(); String jsapi_ticket = wci.getJsapi(); String noncestr = UUID.randomUUID().toString(); String timestamp = Long.toString(System.currentTimeMillis() / 1000); model.addAttribute("appId", appId); model.addAttribute("jsapi_ticket", jsapi_ticket); model.addAttribute("noncestr", noncestr); model.addAttribute("timestamp", timestamp); model.addAttribute("url", url); String signature; try { signature = getSignature(jsapi_ticket,url,noncestr,timestamp); model.addAttribute("signature", signature); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (AesException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * <b>描述:</b> JS-SDK使用許可權簽名 * @return * <br><b>Author:</b> * <br><b>Date:</b> 2017年6月5日 下午4:30:23 * @throws AesException * @throws IOException */ public String getSignature(String jsapi_ticket,String url,String noncestr,String timestamp) throws IOException, AesException{ String s = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; String signature = getSha1(s); return signature; } public static String getSha1(String str) { if (str == null || str.length() == 0) { return null; } char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; try { MessageDigest mdTemp = MessageDigest.getInstance("SHA1"); mdTemp.update(str.getBytes("UTF-8")); byte[] md = mdTemp.digest(); int j = md.length; char buf[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; buf[k++] = hexDigits[byte0 & 0xf]; } return new String(buf); } catch (Exception e) { // TODO: handle exception return null; } }
2、jsp頁面操作
(1)引入js檔案:<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
(2)
$(function(){
wx.config({
debug: false, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
appId: '${appId}', // 必填,公眾號的唯一標識
timestamp: '${timestamp}', // 必填,生成簽名的時間戳
nonceStr: '${noncestr}', // 必填,生成簽名的隨機串
signature: '${signature}',// 必填,簽名,見附錄1
jsApiList: ['closeWindow'] // 必填,需要使用的JS介面列表,所有JS介面列表見附錄2
});
pushHistory();
window.addEventListener("popstate",
function(e) {
wx.closeWindow();
},false);
function pushHistory() {
var url = "#";
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, "title", "#");
}
})
綜上,就可以在返回的時候關閉微信瀏覽器。注:上述(一)(二)都存在一個問題,在頁面載入完畢之後,點選物理返回鍵,效果是成功的;但是當頁面未載入完,物理點選的話js未被觸發,就會按history中的記錄來回跳轉。
(三)要解決上述問題,歸根結底是要讓不想返回的頁面,不要儲存到history。這樣跳轉就不會存在上述問題。
糾結兩天找到的解決方案:大致思路就是說將要不想返回的頁面(以下簡稱A.jsp)的URL進行替換,替換成下一個跳轉頁面B.jsp的URL,當觸發跳轉事件時reload即可,這樣history裡頭存放的是B.jsp的URL,瀏覽器history中沒有存放,當然返回的時候就不會返回的A.jsp嘍。具體如下:
var replaceUrl;
function pushHistory(replaceUrl) {
var state = {
title: "title",
url: replaceUrl
};
window.history.replaceState(state, "title",replaceUrl);
}
//當點選B.jsp跳轉時
$("#btn").click(){
pushHistory("../"+url);//你要跳轉的URL
location.reload();
}
注:這個replaceUrl必須是同域,跨域是不允許的