1. 程式人生 > 程式設計 >探索瀏覽器頁面關閉window.close()的使用詳解

探索瀏覽器頁面關閉window.close()的使用詳解

說起來window.close(),這也是個“不太讓人省心”的角色。因為瀏覽器相容性千差萬別,還對他有諸多限制。

使用語法:

window.close()

場景復現

昨天發現有人在csdn上傳違禁檔案,舉報後來到了這個頁面:

探索瀏覽器頁面關閉window.close()的使用詳解

裡面那個按鈕發現點選無效!
就。。。當時就挺尷尬的。

不過既然它說是【關閉】,當時就想到了這個堪稱“漏洞百出”的close事件,F12開啟控制檯一看:果不其然

探索瀏覽器頁面關閉window.close()的使用詳解

看到這頓時就來了興趣

探索過程和解決方案

為什麼就突然來了興趣呢?

首先,從這行程式碼中可以看出:這個頁面不是通過 window.open() “開啟”的 —— MDN文件中有說明:不是通過window.open()方法開啟的視窗不能(直接)使用close進行關閉 (以前這條是針對Firefox的策略)

顯然,csdn這位工程師也看過文件,所以想用【在本頁面開啟空白頁,然後再強行關閉】的“取巧”方法。但我不知道當時是怎麼測試的,還是說後來瀏覽器又加的限制,這行程式碼在本文所寫時顯然在所有瀏覽器上都不能執行!

現在讓我通過語法解釋一下上面的程式碼:

//摘自:MDN
var window = window.open(url,windowName,[windowFeatures]);

方法明確指出三個引數,第三個引數一般用於在“彈出框頁面”處理長寬限制,和我們當前的問題沒有關係,我們就不再考慮。

MDN對url引數進行了說明,這個引數可以是個路徑,可以是個頁面/圖片/其他瀏覽器支援型別的資源的地址, 如果引數1你寫空串,會在指定的上下文環境中建立一個空頁面

我們看第二個引數windowName, 這個引數表示 你要指定資源在哪個視窗開啟 ,如果你指定的視窗不存在,瀏覽器會建立一個新的視窗,並把這個視窗的window物件命名為windowName(可以通過window.name獲取到),值得注意的是,這並不是這個視窗的【title】,當你在別處使用<a><form>標籤時 可以將target屬性的值寫成 windowName 進行跳轉,訪問,為空時,一樣建立新視窗。

通過此處的描述我們可以知道, windowName的值應該與target的值是相同的。

既然說到了target,正好上面csdn用的也是a標籤,那我們就以a連結為例 (另一方面form不常用),為<a></a>

新增 target 表示我要設定連結的開啟方式

1._self —— 預設值,表示在當前上下文中開啟,不需要寫
2._blank表示我要新建立一個tab/window
3._parent 表示在其上級上下文環境中載入,沒有上級時同_self
4._top表示在其頂級上下文環境中載入,沒有時同_self

所以現在常用的寫法就是:

  • 首先呼叫 window.open('',‘_self') 方法 ,引數1置空 引數2寫為_self 表示我們要在當前頁面載入一個空;
  • 此時彷彿就是一個偷樑換柱的作用,通過載入進來一個空,將我們當前訪問的頁面變成window.open()開啟的頁面

這個時候 是不是就可以愉快地使用window.close()方法併成功關閉當前頁面了?

可以!

筆者可以確切的告訴你,這種方法在本地測試絕大多數瀏覽器上都可以正常使用!
但偏偏在這裡(本文開頭所說例項)不行!

還有一點是:如果你在a標籤的 href 中用了javascript:xxx;寫事件,那就千萬記得不能再加屬性target!

就在我焦頭爛額自我懷疑時,一師兄給我說了一個取巧的解決方案:about:blank

探索瀏覽器頁面關閉window.close()的使用詳解

也可以!但似乎這並不是最好的方法!!!

再回到上面的程式碼,我想了許久,莫不是 瀏覽器相容性 的問題?
為此,我判斷了IE、Firefox、和其餘瀏覽器(因為據說Firefox仍然在這個問題上表現地尤為激烈):

// 相容所有瀏覽器關閉頁面方法
function ClosePage(){  
  if (navigator.userAgent.indexOf("MSIE") > 0){
    if (navigator.userAgent.indexOf("MSIE 6.0") > 0){
      window.opener = null;
      window.close();
    } else {
      window.open('','_top');
      window.top.close();
    }
  } else if (navigator.userAgent.indexOf("Firefox") > 0) {
    window.location.href = 'about:blank';
  } else {
    window.opener = null;
    window.open('','_self','');
    window.close();
  }
}

用這個方法,在各個瀏覽器上找網頁試了一下,效果還不錯。
但…
很多瀏覽器上會有和上面about:blank一樣的效果。

到這裡我就納悶了,到底是為什麼?
可能是瀏覽器對close的實現策略導致的。不過還沒等我納悶完,另一個訊息就來了:這段程式碼放到文首的那個頁面依然不行。。。(更新:在google和Firefox的一些網站如我們也不能用!)

有點小懵,什麼鬼?
csdn這裡究竟用了什麼導致“close事件不能執行”?

一些小建議和結尾

這一點我不得而知。我後來分析了整個頁面,做了程式碼復現,斷點除錯。。。依然沒能發現問題出在哪裡。

不過我從一開始就覺得:這種方式——不論是“關閉頁面”還是“開啟一個空頁面提示”,它的效果似乎都還不如“返回瀏覽器首頁”好:

let historyLen = window.history.length;
window.history.go(-historyLen+1)

更新:
這裡其實是有問題的,因為使用者如果“主動”觸發瀏覽器上面的“返回上一頁”的按鈕,那麼window.history的length值並不會改變,當你再執行window.history.go()的時候就不會有響應了!(但是在本文場景下如果使用者返回了上一頁就不會有這個按鈕了,此問題也就不存在)
筆者還想到了document.referrer,它是用於獲取+改變“從哪裡跳轉過來的”路徑的API,但是很不幸,我發現了一個很神奇的事情:document.referrer=""時,相當於“本頁面” —— 也就是說,它會把上一個頁面也變為當前頁面!
這確實是很神奇的:因為go函式也實現了這個功能——相當於重新整理當前頁。

或者“返回網站首頁”?

location.href="xxx" rel="external nofollow" 

這樣還能再宣傳一波,何樂而不為?

到此這篇關於探索瀏覽器頁面關閉window.close()的使用詳解的文章就介紹到這了,更多相關瀏覽器頁面關閉window.close()內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!