瀏覽器對于我們來說,可能是最熟悉的工具了。記得最早那會Netscape,到后來的Internet Explorer一統(tǒng)江湖,再到現(xiàn)在的FireFox大行其道,瀏覽器市場的爭奪,可謂是硝煙彌漫。熟知的瀏覽器Firefox、Opera、Safari、IE、Chrome以外,據(jù)說世界上還有近百種瀏覽器。
在我們的產(chǎn)品開發(fā)過程中,經(jīng)常要考慮瀏覽器兼容問題,以適應(yīng)不同的用戶人群,同時也減少因?yàn)g覽器兼容問題所帶來的服務(wù)量。一般來說,通過JavaScript判斷瀏覽器類型,我們通常使用兩種方法,一種是根據(jù)各種瀏覽器獨(dú)有的屬性來分辨,另一種是通過分析瀏覽器的user-Agent屬性來判斷的。在許多情況下,值判斷出瀏覽器類型之后,還需判斷瀏覽器版本才能處理兼容性問題,而判斷瀏覽器的版本一般只能通過分析瀏覽器的User-Agent才能知道?,F(xiàn)在比較流行的javascript框架,都有瀏覽器兼容的判斷代碼,像jquery、YUI就是使用User-Agent,而Mootools則是使用用各種瀏覽器獨(dú)有的屬性來分辨。
先來看看什么是User-Agent?User-Agent是HTTP請求中的用戶標(biāo)識,一般發(fā)送一個能夠代表客戶端類型的字符串,比如瀏覽器類型 操作系統(tǒng)等信息。User-Agent 的約定格式是:應(yīng)用名,跟一個斜線,跟版本號,剩下的是自由的格式。
我們先來看一下常用瀏覽器的User-Agent:
IE
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)
其中,版本號是MSIE之后的數(shù)字。
Firefox
Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1
Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070309 Firefox/2.0.0.3
Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803 Firefox/1.5.0.12
其中,版本號是Firefox之后的數(shù)字。
·Safari·
Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, ** Gecko) Version/3.1 Safari/525.13
Mozilla/5.0 (iPhone; U; CPU ** Mac OS X) AppleWebKit/420.1 (KHTML, ** Gecko) Version/3.0 Mobile/4A93 Safari/419.3
其版本號是Version之后的數(shù)字。
Chrome
Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, ** Gecko) Chrome/0.2.149.27 Safari/525.13
其中,版本號在Chrome只后的數(shù)字。
一.基于User-Agent信息的實(shí)現(xiàn)
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
(s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
//以下進(jìn)行測試
if (Sys.ie) document.write('IE: ' + Sys.ie);
if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
if (Sys.opera) document.write('Opera: ' + Sys.opera);
if (Sys.safari) document.write('Safari: ' + Sys.safari);
二.根據(jù)瀏覽器特有屬性判斷
var Browser = {
Engine: {name: 'unknown', version: 0},
Features: {
xpath: !!(document.evaluate), // 是否支持 XPath
air: !!(window.runtime), // 是否支持 Air 擴(kuò)展
query: !!(document.querySelector) // 是否支持 CSS 選擇器
},
Engines: {
// 判斷 Opera
presto: function () {
return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
},
// 判斷 IE,根據(jù) ActiveX 和 特有的 XMLHttpRequest 對象
trident: function () {
return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? 5 : 4);
},
// Webkit 核心的瀏覽器,如 Safari 和 Chrome
webkit: function () {
return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
},
// Mozilla Gecko 核心瀏覽器,如 Firefox
gecko: function () {
return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18);
}
}
};
或者
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
window.ActiveXObject ? Sys.ie = ua.match(/msie ([\d.]+)/)[1] :
document.getBoxObjectFor ? Sys.firefox = ua.match(/firefox\/([\d.]+)/)[1] :
window.MessageEvent && !document.getBoxObjectFor ? Sys.chrome = ua.match(/chrome\/([\d.]+)/)[1] :
window.opera ? Sys.opera = ua.match(/opera.([\d.]+)/)[1] :
window.openDatabase ? Sys.safari = ua.match(/version\/([\d.]+)/)[1] : 0;
//以下進(jìn)行測試
if (Sys.ie) document.write('IE: ' + Sys.ie);
if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
if (Sys.opera) document.write('Opera: ' + Sys.opera);
if (Sys.safari) document.write('Safari: ' + Sys.safari);
但是,這兩種檢測方法都有其局限性,User-Agent 是可以通過代碼修改的,所以純粹檢測User-Agent可能會帶來一定的風(fēng)險,而且ie8的Compatibility View 功能造成單瀏覽器會“原生”多個 User-agent 。使用不同特征來判斷瀏覽器的方法,
雖然在速度上比用正則表達(dá)式分析userAgent要來的快,不過這些特征可能會隨瀏覽器版本而變化。比如,一種瀏覽器本來獨(dú)有的特性取得了市場上的成功,其他瀏覽器也就可能跟著加入該特性,從而使該瀏覽器的獨(dú)有特征消失,導(dǎo)致我們的判斷失敗。因此,
相對比較保險的做法是通過解析userAgent中的特征來判斷瀏覽器類型。何況,反正判斷版本信息也需要解析瀏覽器的userAgent的。所以,在我們的實(shí)際編程中,還得根據(jù)實(shí)際情況來決定使用哪種方法來判斷瀏覽器類型和版本。
ppk on javascript中有關(guān)瀏覽器檢測的看法和建議
1、Opera,iCab等非主流瀏覽器提供給用戶自己修改識別字符串,以訪問更多的網(wǎng)站。
2、Opera 在navigator.userAgent永遠(yuǎn)包含一個子字符串Opera,即使當(dāng)它處于偽裝模式時也一樣。而且Opera是唯一支持window.opera屬性的瀏覽器
3、Safari、iCab和Konqueror 在navigator.userAgent有它們自己的標(biāo)識符,那他們也有可能不包含,為了偽裝。
4、Gecko Mozilla的識別字符串中通常包含Gecko,不過,Safari的默認(rèn)字符串中也包含Gecko
5、MSIE 大部分瀏覽器都拿它來偽裝,因此它的出現(xiàn)說明不了任何問題。
三.ppk中有關(guān)瀏覽器檢測的代碼
var BrowserDetect = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
this.version = this.searchVersion(navigator.userAgent)
|| this.searchVersion(navigator.appVersion)
|| "an unknown version";
this.OS = this.searchString(this.dataOS) || "an unknown OS";
},
searchString: function (data) {
for (var i=0;i<data.length;i++) {
var dataString = data[i].string;
var dataProp = data[i].prop;
this.versionSearchString = data[i].versionSearch || data[i].identity;
if (dataString) {
if (dataString.indexOf(data[i].subString) != -1)
return data[i].identity;
}
else if (dataProp)
return data[i].identity;
}
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index == -1) return;
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
},
dataBrowser: [
{
string: navigator.userAgent,
subString: "Chrome",
identity: "Chrome"
},
{ string: navigator.userAgent,
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
},
{
string: navigator.vendor,
subString: "Apple",
identity: "Safari",
versionSearch: "Version"
},
{
prop: window.opera,
identity: "Opera"
},
{
string: navigator.vendor,
subString: "iCab",
identity: "iCab"
},
{
string: navigator.vendor,
subString: "KDE",
identity: "Konqueror"
},
{
string: navigator.userAgent,
subString: "Firefox",
identity: "Firefox"
},
{
string: navigator.vendor,
subString: "Camino",
identity: "Camino"
},
{ // for newer Netscapes (6+)
string: navigator.userAgent,
subString: "Netscape",
identity: "Netscape"
},
{
string: navigator.userAgent,
subString: "MSIE",
identity: "Explorer",
versionSearch: "MSIE"
},
{
string: navigator.userAgent,
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
},
{ // for older Netscapes (4-)
string: navigator.userAgent,
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}
],
dataOS : [
{
string: navigator.platform,
subString: "Win",
identity: "Windows"
},
{
string: navigator.platform,
subString: "Mac",
identity: "Mac"
},
{
string: navigator.userAgent,
subString: "iPhone",
identity: "iPhone/iPod"
},
{
string: navigator.platform,
subString: "Linux",
identity: "Linux"
}
]
};
BrowserDetect.init();
document.write('你正在使用的是:' + BrowserDetect.browser + ' ' + BrowserDetect.version + ' on ' + BrowserDetect.OS + '!');