天天看點

使用者代理字元串檢測技術「2」

作者:飛朋張

4. 識别Windows作業系統

在Windows平台下,還可以從使用者代理字元串中進一步取得具體的作業系統資訊。在Windows XP之前,Windows有兩種版本,分别針對家庭使用者和商業使用者。針對家庭使用者的版本分别是Windows 95、98和Windows ME。而針對商業使用者的版本則一直叫做Window NT,最後由于市場原因改名為Windows 2000。這兩個産品線後來又合并成一個由Windows NT發展而來的公共的代碼基,代表産品就是Windows XP。随後,微軟在Windows XP基礎上又建構了Windows Vista。

隻有了解這些資訊,才能搞清楚使用者代理字元串中Windows作業系統的具體版本。下表列出了不同浏覽器在表示不同的Windows作業系統時給出的不同字元串。

Windows版本IE 4+GeckoOpera < 7Opera 7+WebKit95"Windows 95""Win95""Windows 95""Windows 95"n/a98"Windows 98""Win98""Windows 98""Windows 98"n/aNT 4.0"Windows NT""WinNT4.0""Windows NT 4.0""Windows NT 4.0"n/a2000"Windows NT 5.0""Windows NT 5.0""Windows 2000""Windows NT 5.0"n/aME"Win 9x 4.90""Win 9x 4.90""Windows ME""Win 9x 4.90"n/aXP"Windows NT 5.1""Windows NT 5.1""Windows XP""Windows NT 5.1""Windows NT 5.1"Vista"Windows NT 6.0""Windows NT 6.0"n/a"Windows NT 6.0""Windows NT 6.0"7"Windows NT 6.1""Windows NT 6.1"n/a"Windows NT 6.1""Windows NT 6.1"

由于使用者代理字元串中的Windows作業系統版本表示方法各異,是以檢測代碼并不十分直覺。好在,從Windows 2000開始,表示作業系統的字元串大部分都還相同,隻有版本号有變化。為了檢測不同的Windows作業系統,必須要使用正規表達式。由于使用Opera 7之前版本的使用者已經不多了,是以我們可以忽略這部分浏覽器。

第一步就是比對Windows 95和Windows 98這兩個字元串。對這兩個字元串,隻有Gecko與其他浏覽器不同,即沒有"dows",而且"Win"與版本号之間沒有空格。要比對這個模式,可以使用下面這個簡單的正規表達式。

/Win(?:dows )?([^do]{2})/

這個正規表達式中的捕獲組會傳回作業系統的版本。由于版本可能是任何兩個字元編碼(例如95、98、9x、NT、ME及XP),是以要使用兩個非空格字元。

Gecko在表示Windows NT時會在末尾添加"4.0",與其查找實際的字元串,不如像下面這樣查找小數值更合适。

/Win(?:dows )?([^do]{2})(\d+\.\d+)?/

這樣,正規表達式中就包含了第二個捕獲組,用于取得NT的版本号。由于該版本号對于Windows 95和Windows 98而言是不存在的,是以必須設定為可選。這個模式與Opera表示Windows NT的字元串之間唯一的差別,就是"NT"與"4.0"之間的空格,這在模式中很容易添加。

/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/

經過一番修改之後,這個正規表達式也可以成功地比對Windows ME、Windows XP和Windows Vista的字元串了。具體來說,第一個捕獲組将會比對95、98、9x、NT、ME或XP。第二個捕獲組則隻針對Windows ME及所有Windows NT的變體。這個資訊可以作為具體的作業系統資訊儲存在system.win屬性中,如下所示。

if (system.win){

if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){

if (RegExp["$1"] == "NT"){

switch(RegExp["$2"]){

case "5.0":

system.win = "2000";

break;

case "5.1":

system.win = "XP";

break;

case "6.0":

system.win = "Vista";

break;

case "6.1":

system.win = "7";

break;

default:

system.win = "NT";

break;

}

} else if (RegExp["$1"] == "9x"){

system.win = "ME";

} else {

system.win = RegExp["$1"];

}

}

}

如果system.win的值為true,那麼就使用這個正規表達式從使用者代理字元串中提取具體的資訊。鑒于Windows将來的某個版本也許不能使用這個方法來檢測,是以第一步應該先檢測使用者代理字元串是否與這個模式比對。

在模式比對的情況下,第一個捕獲組中可能會包含"95"、"98"、"9x"或"NT"。如果這個值是"NT",可以将system.win設定為相應作業系統的字元串;如果是"9x",那麼system.win就要設定成"ME";如果是其他值,則将所捕獲的值直接賦給system.win。有了這些檢測平台的代碼後,我們就可以編寫如下代碼。

if (client.system.win){

if (client.system.win == "XP") {

//說明是XP

} else if (client.system.win == "Vista"){

//說明是Vista

}

}

由于非空字元串會轉換為布爾值true,是以可以将client.system.win作為布爾值用在if語句中。而在需要更多有關作業系統的資訊時,則可以使用其中儲存的字元串值。

5. 識别移動裝置

2006年到2007年,移動裝置中Web浏覽器的應用呈爆炸性增長。四大主要浏覽器都推出了手機版和在其他裝置中運作的版本。要檢測相應的裝置,第一步是為要檢測的所有移動裝置添加屬性,如下所示。

var client = function(){

var engine = {

//呈現引擎

ie: 0,

gecko: 0,

webkit: 0,

khtml: 0,

opera: 0,

//具體的版本号

ver: null

};

var browser = {

//浏覽器

ie: 0,

firefox: 0,

safari: 0,

konq: 0,

opera: 0,

chrome: 0,

//具體的版本号

ver: null

};

var system = {

win: false,

mac: false,

x11: false,

//移動裝置iphone: false,ipod: false,ipad: false,ios: false,android: false,nokiaN: false,winMobile: false};

//在此檢測呈現引擎、平台和裝置

return {

engine: engine,

browser: browser,

system: system

};

}();

然後,通常簡單地檢測字元串"iPhone"、"iPod"和"iPad",就可以分别設定相應屬性的值了。

system.iphone = ua.indexOf("iPhone") > -1;

system.ipod = ua.indexOf("iPod") > -1;

system.ipod = ua.indexOf("iPad") > -1;

除了知道iOS裝置,最好還能知道iOS的版本号。在iOS 3之前,使用者代理字元串中隻包含"CPU like Mac OS",後來iPhone中又改成"CPU iPhone OS 3_0 like Mac OS X",iPad中又改成"CPU OS 3_2 like Mac OS X"。也就是說,檢測iOS需要正規表達式反映這些變化。

//檢測iOS版本

if (system.mac && ua.indexOf("Mobile") > -1){

if (/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)){

system.ios = parseFloat(RegExp.$1.replace("_", "."));

} else {

system.ios = 2; //不能真正檢測出來,是以隻能猜測

}

}

檢查系統是不是Mac OS、字元串中是否存在"Mobile",可以保證無論是什麼版本,system.ios中都不會是0。然後,再使用正規表達式确定是否存在iOS的版本号。如果有,将system.ios設定為表示版本号的浮點值;否則,将版本設定為2。(因為沒有辦法确定到底是什麼版本,是以設定為更早的版本比較穩妥。)

檢測Android作業系統也很簡單,也就是搜尋字元串"Android"并取得緊随其後的版本号。

//檢測Android版本

if (/Android (\d+\.\d+)/.test(ua)){

system.android = parseFloat(RegExp.$1);

}

由于所有版本的Android都有版本值,是以這個正規表達式可以精确地檢測所有版本,并将system.android設定為正确的值。

諾基亞N系列手機使用的也是WebKit,其使用者代理字元串與其他基于WebKit的手機很相似,例如:

Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/11.0.026; Profile MIDP-2.0

Configuration/CLDC-1.1) AppleWebKit/413 (KHTML, like Gecko) Safari/413

雖然諾基亞N系列手機在使用者代理字元串中聲稱使用的是"Safari",但實際上并不是Safari,盡管确實是基于WebKit引擎。隻要像下面檢測一下使用者代理字元串中是否存在"NokiaN",就足以确定是不是該系列的手機了。

system.nokiaN = ua.indexOf("NokiaN") > -1;

在了解這些裝置資訊的基礎上,就可以通過下列代碼來确定使用者使用的是什麼裝置中的WebKit來通路網頁:

if (client.engine.webkit){

if (client.system. iOS){

//iOS手機的内容

} else if (client.system.android){

//Android手機的内容

} else if (client.system.nokiaN){

//諾基亞手機的内容

}

}

最後一種主要的移動裝置平台是Windows Mobile(也稱為Windows CE),用于Pocket PC和Smartphone中。由于從技術上說這些平台都屬于Windows平台,是以Windows平台和作業系統都會傳回正确的值。對于Windows Mobile 5.0及以前版本,這兩種裝置的使用者代理字元串非常相似,如下所示:

Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)

Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; Smartphone; 176x220)

第一個來自Pocket PC中的移動Internet Explorer 4.01,第二個來自Smartphone中的同一個浏覽器。當Windows作業系統檢測腳本檢測這兩個字元串時,system.win将被設定為"CE",是以在檢測Windows Mobile時可以使用這個值:

system.winMobile = (system.win == "CE");

不建議測試字元串中的"PPC"或"Smartphone",因為在Windows Mobile 5.0以後版本的浏覽器中,這些記号已經被移除了。不過,一般情況下,隻知道某個裝置使用的是Windows Mobile也就足夠了。

Windows Phone 7的使用者代理字元串稍有改進,基本格式如下:

Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0)

Asus;Galaxy6

其中,Windows操作符的辨別符與已往完全不同,是以在這個使用者代理中client.system.win等于"Ph"。從中可以取得有關系統的更多資訊:

//windows mobile

if (system.win == "CE"){

system.winMobile = system.win;

} else if (system.win == "Ph"){

if(/Windows Phone OS (\d+.\d+)/.test(ua)){;

system.win = "Phone";

system.winMobile = parseFloat(RegExp["$1"]);

}

}

如果system.win的值是"CE",就說明是老版本的Windows Mobile,是以system.winMobile會被設定為相同的值(隻能知道這個資訊)。如果system.win的值是"Ph",那麼這個裝置就可能是Windows Phone 7或更新版本。是以就用正規表達式來測試格式并提取版本号,将system.win的值重置為"Phone",而将system.winMobile設定為版本号。

6. 識别遊戲系統

除了移動裝置之外,視訊遊戲系統中的Web浏覽器也開始日益普及。任天堂Wii和Playstation 3或者内置Web浏覽器,或者提供了浏覽器下載下傳。Wii中的浏覽器實際上是定制版的Opera,是專門為Wii Remote設計的。Playstation的浏覽器是自己開發的,沒有基于前面提到的任何呈現引擎。這兩個浏覽器中的使用者代理字元串如下所示:

Opera/9.10 (Nintendo Wii;U; ; 1621; en)

Mozilla/5.0 (PLAYSTATION 3; 2.00)

第一個字元串來自運作在Wii中的Opera,它忠實地繼承了Opera最初的使用者代理字元串格式(Wii上的Opera不具備隐瞞身份的能力)。第二個字元串來自Playstation3,雖然它為了相容性而将自己辨別為Mozilla 5.0,但并沒有給出太多資訊。而且,裝置名稱居然全部使用了大寫字母,讓人覺得很奇怪;強烈希望将來的版本能夠改變這種情況。

在檢測這些裝置以前,我們必須先為client.system中添加适當的屬性,如下所示:

var client = function(){

var engine = {

//呈現引擎

ie: 0,

gecko: 0,

webkit: 0,

khtml: 0,

opera: 0,

//具體的版本号

ver: null

};

var browser = {

//浏覽器

ie: 0,

firefox: 0,

safari: 0,

konq: 0,

opera: 0,

chrome: 0,

//具體的版本号

ver: null

};

var system = {

win: false,

mac: false,

x11: false,

//移動裝置

iphone: false,

ipod: false,

ipad: false,

ios: false,

android: false,

nokiaN: false,

winMobile: false,

//遊戲系統wii: false,ps: false

};

//在此檢測呈現引擎、平台和裝置

return {

engine: engine,

browser: browser,

system: system

};

}();

檢測前述遊戲系統的代碼如下:

system.wii = ua.indexOf("Wii") > -1;

system.ps = /playstation/i.test(ua);

對于Wii,隻要檢測字元串"Wii"就夠了,而其他代碼将發現這是一個Opera浏覽器,并将正确的版本号儲存在client.browser.opera中。對于Playstation,我們則使用正規表達式來以不區分大小寫的方式測試使用者代理字元串。

想要了解更多Java基礎知識,可以點選評論區連結和小編一起學習java吧,此視訊教程為初學者而著,零基礎入門篇!給同學們帶來全新的Java300集課程啦!java零基礎小白自學Java必備優質教程_手把手圖解學習Java,讓學習成為一種享受_哔哩哔哩_bilibili

繼續閱讀