JavaScript的瀏覽器檢測

 由於每個瀏覽器都具有自己獨到的擴展,所以在開發階段來判斷瀏覽器是一個非常重要

的步驟。雖然瀏覽器開發商在公共接口方面投入了很多精力,努力的去支持最常用的公共功
能;但在現實中,瀏覽器之間的差異,以及不同瀏覽器的“怪癖”卻是非常多的,因此客戶
端檢測除了是一種補救措施,更是一種行之有效的開發策略。
 
一.navigator對象
navigator 對象最早由Netscape Navigator2.0 引入的navigator 對象,現在已經成爲識別客
戶端瀏覽器的事實標準。與之前的BOM 對象一樣,每個瀏覽器中的navigator 對象也都有
一套自己的屬性。

 

 

1.瀏覽器及版本號

不同的瀏覽器支持的功能、屬性和方法各有不同。比如IE 和Firefox 顯示的頁面可能就

會有所略微不同。

  1. alert('瀏覽器名稱:' + navigator.appName); 
  2. alert('瀏覽器版本:' + navigator.appVersion); 
  3. alert('瀏覽器用戶代理字符串:' + navigator.userAgent); 
  4. alert('瀏覽器所在的系統:' + navigator.platform); 

 2.瀏覽器嗅探器
瀏覽器嗅探器是一段程序,有了它,瀏覽器檢測就變得簡單了。我們這裏提供了一個
browserdetect.js 文件,用於判斷瀏覽器的名稱、版本號及操作系統。

  1. alert(BrowserDetect.browser); //名稱 
  2. alert(BrowserDetect.version); //版本 
  3. alert(BrowserDetect.OS) //系統 

3.檢測插件
插件是一類特殊的程序。他可以擴展瀏覽器的功能,通過下載安裝完成。比如,在線音
樂、視頻動畫等等插件。
navigator 對象的plugins 屬性,這個一個數組。存儲在瀏覽器已安裝插件的完整列表。

  1. //列出所有的插件名 
  2. for (var i = 0; i < navigator.plugins.length; i ++) { 
  3. document.write(navigator.plugins[i].name + '<br />'); 
  4. //檢測非IE 瀏覽器插件是否存在 
  5. function hasPlugin(name) { 
  6. var name = name.toLowerCase(); 
  7. for (var i = 0; i < navigator.plugins.length; i ++) { 
  8. if (navigator.plugins[i].name.toLowerCase().indexOf(name) > -1) { 
  9. return true
  10. return false
  11. alert(hasPlugin('Flash')); //檢測Flash 是否存在 
  12. alert(hasPlugin('java')) //檢測Java 是否存在 

4.ActiveX
IE 瀏覽器沒有插件,但提供了ActiveX 控件。ActiveX 控件一種在Web 頁面中嵌入對象
或組件的方法。
由於在JS 中,我們無法把所有已安裝的ActiveX 控件遍歷出來,但我們還是可以去驗
證是否安裝了此控件。

  1. //檢測IE 中的控件 
  2. function hasIEPlugin(name) { 
  3. try { 
  4. new ActiveXObject(name); 
  5. return true
  6. catch (e) { 
  7. return false
  8. //檢測Flash 
  9. alert(hasIEPlugin('ShockwaveFlash.ShockwaveFlash')); 

PS:ShockwaveFlash.ShockwaveFlash 是IE 中代表FLASH 的標識符,你需要檢查哪種
控件,必須先獲取它的標識符。

  1. //跨瀏覽器檢測是否支持Flash 
  2. function hasFlash() { 
  3. var result = hasPlugin('Flash'); 
  4. if (!result) { 
  5. result = hasIEPlugin('ShockwaveFlash.ShockwaveFlash'); 
  6. return result; 
  7. //檢測Flash 
  8. alert(hasFlash()); 

5.MIME 類型
MIME 是指多用途因特網郵件擴展。它是通過因特網發送郵件消息的標準格式。現在也
被用於在因特網中交換各種類型的文件。
PS:mimeType[]數組在IE 中不產生輸出。

 

  1. //遍歷非IE 下所有MIME 類型信息 
  2. for (var i = 0; i < navigator.mimeTypes.length; i++) { 
  3. if (navigator.mimeTypes[i].enabledPlugin != null) { 
  4. document.write('<dl>'); 
  5. document.write('<dd>類型名稱:' + navigator.mimeTypes[i].type + '</dd>'); 
  6. document.write('<dd>類型引用:' + navigator.mimeTypes[i].enabledPlugin.name + 
  7. '</dd>'); 
  8. document.write('<dd>類型描述:' + navigator.mimeTypes[i].description + '</dd>'); 
  9. document.write('<dd>類型後綴:' + navigator.mimeTypes[i].suffixes + '</dd>'); 
  10. document.write('</dl>'

二.客戶端檢測
客戶端檢測一共分爲三種,分別爲:能力檢測、怪癖檢測和用戶代理檢測,通過這三種
檢測方案,我們可以充分的瞭解當前瀏覽器所處系統、所支持的語法、所具有的特殊性能。
1.能力檢測
能力檢測又稱作爲特性檢測,檢測的目標不是識別特定的瀏覽器,而是識別瀏覽器的能
力。能力檢測不必估計特定的瀏覽器,只需要確定當前的瀏覽器是否支持特定的能力,就可
以給出可行的解決方案。

  1. //BOM 章節的一段程序 
  2. var width = window.innerWidth; //如果是非IE 瀏覽器 
  3. if (typeof width != 'number') { //如果是IE,就使用document 
  4. if (document.compatMode == 'CSS1Compat') { 
  5. width = document.documentElement.clientWidth; 
  6. else { 
  7. width = document.body.clientWidth; //非標準模式使用body 

PS:上面其實有兩塊地方使用了能力檢測,第一個就是是否支持innerWidth 的檢測,
第二個就是是否是標準模式的檢測,這兩個都是能力檢測。


2.怪癖檢測(bug 檢測)
與能力檢測類似,怪癖檢測的目標是識別瀏覽器的特殊行爲。但與能力檢測確認瀏覽器
支持什麼能力不同,怪癖檢測是想要知道瀏覽器存在什麼缺陷(bug)。
bug 一般屬於個別瀏覽器獨有,在大多數新版本的瀏覽器被修復。在後續的開發過程中,
如果遇到瀏覽器bug 我們再詳細探討。

  1. var box = { 
  2. toString : function () {} //創建一個toString(),和原型中重名了 
  3. }; 
  4. for (var o in box) { 
  5. alert(o); //IE 瀏覽器的一個bug,不識別了 

3.用戶代理檢測
用戶代理檢測通過檢測用戶代理字符串來確定實際使用的瀏覽器。在每一次HTTP 請求
過程中,用戶代理字符串是作爲響應首部發送的,而且該字符串可以通過JavaScript 的
navigator.userAgent 屬性訪問。
用戶代理代理檢測,主要通過navigator.userAgent 來獲取用戶代理字符串的,通過這組
字符串,我們來獲取當前瀏覽器的版本號、瀏覽器名稱、系統名稱。
PS:在服務器端,通過檢測用戶代理字符串確定用戶使用的瀏覽器是一種比較廣爲接
受的做法。但在客戶端,這種測試被當作是一種萬不得已的做法,且飽受爭議,其優先級排
在能力檢測或怪癖檢測之後。飽受爭議的原因,是因爲它具有一定的欺騙性。

  1. document.write(navigator.userAgent); //得到用戶代理字符串 
  2. //Firefox14.0.1 
  3. Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1 
  4. //Firefox3.6.28 
  5. Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.28) Gecko/20120306 Firefox/3.6.28 
  6. //Chrome20.0.1132.57 m 
  7. Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.11 (KHTML, like Gecko)Chrome/20.0.1132.57 Safari/536.11 
  8. //Safari5.1.7 
  9. Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 
  10. //IE7.0 
  11. Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 
  12. 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 
  13. //IE8.0 
  14. Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 
  15. 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 
  16. //IE6.0 
  17. Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 
  18. 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) 
  19. //Opera12.0 
  20. Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.10.289 Version/12.00 
  21. //Opera7.54 
  22. Opera/7.54 (Windows NT 5.1; U) [en] 
  23. //Opera8 
  24. Opera/8.0 (Window NT 5.1; U; en) 
  25. Konqueror (Linux 集成,基於KHTML 呈現引擎的瀏覽器) 
  26. Mozilla/5.0 (compatible; Konqueror/3.5; SunOS) KHTML/3.5.0 (like Gecko) 

只要仔細的閱讀這些字符串,我們可以發現,這些字符串包含了瀏覽器的名稱、版本和
所宿主的操作系統。


每個瀏覽器有它自己的呈現引擎:所謂呈現引擎,就是用來排版網頁和解釋瀏覽器的引
擎。通過代理字符串發現,我們歸納出瀏覽器對應的引擎:
IE -- Trident, IE8 體現出來了,之前的未體現
Firefox -- Gecko,
Opera -- Presto, 舊版本根本無法體現呈現引擎
Chrome -- WebKit WebKit 是KHTML 呈現引擎的一個分支,後獨立開來
Safari -- WebKit
Konqueror -- KHTML


由上面的情況,我們需要檢測呈現引擎可以分爲五大類:IE、Gecko、WebKit、KHTML
和Opera。

  1. var client = function () { //創建一個對象 
  2. var engine = { //呈現引擎 
  3. ie : false
  4. gecko : false
  5. webkit : false
  6. khtml : false
  7. opera : false
  8. ver : 0 //具體的版本號 
  9. }; 
  10. return { 
  11. engine : engine //返回呈現引擎對象 
  12. }; 
  13. }(); //自我執行 
  14. alert(client.engine.ie); //獲取ie 

以上的代碼實現了五大引擎的初始化工作,分別給予true 的初值,並且設置版本號爲0。
下面我們首先要做的是判斷Opera,因爲Opera 瀏覽器支持window.opera 對象,通過這
個對象,我們可以很容易獲取到Opera 的信息。

  1. for (var p in window.opera) { //獲取window.opera 對象信息 
  2. document.write(p + "<br />"); 
  3. if (window.opera) { //判斷opera 瀏覽器 
  4. engine.ver = window.opera.version(); //獲取opera 呈現引擎版本 
  5. engine.opera = true//設置真 

接下來,我們通過正則表達式來獲取WebKit 引擎和它的版本號。

  1. else if (/AppleWebKit\/(\S+)/.test(ua)) { //正則WebKit 
  2. engine.ver = RegExp['$1']; //獲取WebKit 版本號 
  3. engine.webkit = true

然後,我們通過正則表達式來獲取KHTML 引擎和它的版本號。由於這款瀏覽器基於
Linux,我們無法測試。

  1. //獲取KHTML 和它的版本號 
  2. else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)) { 
  3. engine.ver = RegExp['$1']; 
  4. engine.khtml = true

下面,我們通過正則表達式來獲取Gecko 引擎和它的版本號。

  1. else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) { //獲取Gecko 和它的版本號 
  2. engine.ver = RegExp['$1']; 
  3. engine.gecko = true

最後,我們通過正則表達式來獲取IE 的引擎和它的版本號。因爲IE8 之前沒有呈現引
擎,所以,我們只有通過"MSIE"這個共有的字符串來獲取。

  1. else if (/MSIE ([^;]+)/.test(ua)) { //獲取IE 和它的版本號 
  2. engine.ver = RegExp['$1']; 
  3. engine.ie = true

上面獲取各個瀏覽器的引擎和引擎的版本號,但大家也發現了,其實有些確實是瀏覽器
的版本號。所以,下面,我們需要進行瀏覽器名稱的獲取和瀏覽器版本號的獲取。
根據目前的瀏覽器市場份額,我們可以給一下瀏覽器做檢測:IE、Firefox、konq、opera、
chrome、safari。

  1. var browser = { //瀏覽器對象 
  2. ie : false
  3. firefox : false
  4. konq : false
  5. opera : false
  6. chrome : false
  7. safari : false
  8. ver : 0, //具體版本 
  9. name : '' //具體的瀏覽器名稱 
  10. }; 

對於獲取IE 瀏覽器的名稱和版本,可以直接如下:

  1. else if (/MSIE ([^;]+)/.test(ua)) { 
  2. engine.ver = browser.ver = RegExp['$1']; //設置版本 
  3. engine.ie = browser.ie = true//填充保證爲true 
  4. browser.name = 'Internet Explorer'//設置名稱 

對於獲取Firefox 瀏覽器的名稱和版本,可以如下:

  1. else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) { 
  2. engine.ver = RegExp['$1']; 
  3. engine.gecko = true
  4. if (/Firefox\/(\S+)/.test(ua)) { 
  5. browser.ver = RegExp['$1']; //設置版本 
  6. browser.firefox = true//填充保證爲true 
  7. browser.name = 'Firefox'//設置名稱 

對於獲取Chrome 和safari 瀏覽器的名稱和版本,可以如下:

  1. else if (/AppleWebKit\/(\S+)/.test(ua)) { 
  2. engine.ver = RegExp['$1']; 
  3. engine.webkit = parseFloat(engine.ver); 
  4. if (/Chrome\/(\S+)/.test(ua)) { 
  5. browser.ver = RegExp['$1']; 
  6. browser.chrome = true
  7. browser.name = 'Chrome'
  8. else if (/Version\/(\S+)/.test(ua)) { 
  9. browser.ver = RegExp['$1']; 
  10. browser.chrome = true
  11. browser.name = 'Safari'

PS:對於Safari3 之前的低版本,需要做WebKit 的版本號近似映射。而這裏,我們將
不去深究,已提供代碼。
瀏覽器的名稱和版本號,我們已經準確的獲取到,最後,我們想要去獲取瀏覽器所宿主
的操作系統。

  1. var system = { //操作系統 
  2. win : false//windows 
  3. mac : false//Mac 
  4. x11 : false //Unix、Linux 
  5. }; 
  6. var p = navigator.platform; //獲取系統 
  7. system.win = p.indexOf('Win') == 0; //判斷是否是windows 
  8. system.mac = p.indexOf('Mac') == 0; //判斷是否是mac 
  9. system.x11 = (p == 'X11') || (p.indexOf('Linux') == 0) //判斷是否是Unix、Linux 

PS:這裏我們也可以通過用戶代理字符串獲取到windows 相關的版本,這裏我們就不
去深究了,提供代碼和對應列表。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章