需求描述:js腳本判斷網頁是在什麼環境中打開的。內置瀏覽器,還是app內嵌入式的webview打開的,亦或是在微信瀏覽器內打開的,還是用pc端打開的。
查了一圈資料,原理基本上就是通過navigator
對象上的信息來做文章,更具體一點是,navigator.userAgent
這個對象上的信息。
借鑑(chāo xí)zepto.js的瀏覽器嗅探代碼,改寫爲下面這樣的。
// 瀏覽器嗅探
export function detect(navigator) {
let ua = navigator.userAgent;
let platform = navigator.platform;
let os = {},
browser = {},
webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),
android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
osx = !!ua.match(/\(Macintosh\; Intel /),
ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
win = /Win\d{2}|Windows/.test(platform),
wp = ua.match(/Windows Phone ([\d.]+)/),
touchpad = webos && ua.match(/TouchPad/),
kindle = ua.match(/Kindle\/([\d.]+)/),
silk = ua.match(/Silk\/([\d._]+)/),
blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
playbook = ua.match(/PlayBook/),
chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
firefox = ua.match(/Firefox\/([\d.]+)/),
firefoxos = ua.match(/\((?:Mobile|Tablet); rv:([\d.]+)\).*Firefox\/[\d.]+/),
ie =
ua.match(/MSIE\s([\d.]+)/) ||
ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),
webview =
!chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
safari =
webview ||
ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/),
weixin = ua.match(/MicroMessenger/i);
// if (browser.webkit = !!webkit) browser.version = webkit[1]
if (webkit) {
browser.webkit = !!webkit;
browser.version = webkit[1];
}
if (android) (os.android = true), (os.version = android[2]);
if (iphone && !ipod)
(os.ios = os.iphone = true), (os.version = iphone[2].replace(/_/g, "."));
if (ipad)
(os.ios = os.ipad = true), (os.version = ipad[2].replace(/_/g, "."));
if (ipod)
(os.ios = os.ipod = true),
(os.version = ipod[3] ? ipod[3].replace(/_/g, ".") : null);
if (wp) (os.wp = true), (os.version = wp[1]);
if (webos) (os.webos = true), (os.version = webos[2]);
if (touchpad) os.touchpad = true;
if (blackberry) (os.blackberry = true), (os.version = blackberry[2]);
if (bb10) (os.bb10 = true), (os.version = bb10[2]);
if (rimtabletos) (os.rimtabletos = true), (os.version = rimtabletos[2]);
if (playbook) browser.playbook = true;
if (kindle) (os.kindle = true), (os.version = kindle[1]);
if (silk) (browser.silk = true), (browser.version = silk[1]);
if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
if (chrome) (browser.chrome = true), (browser.version = chrome[1]);
if (firefox) (browser.firefox = true), (browser.version = firefox[1]);
if (firefoxos) (os.firefoxos = true), (os.version = firefoxos[1]);
if (ie) (browser.ie = true), (browser.version = ie[1]);
if (safari && (osx || os.ios || win)) {
browser.safari = true;
if (!os.ios) browser.version = safari[1];
}
if (webview) browser.webview = true;
if (weixin) browser.wx = true; // 微信瀏覽器
os.tablet = !!(
ipad ||
playbook ||
(android && !ua.match(/Mobile/)) ||
(firefox && ua.match(/Tablet/)) ||
(ie && !ua.match(/Phone/) && ua.match(/Touch/))
);
os.phone = !!(
!os.tablet &&
!os.ipod &&
(android ||
iphone ||
webos ||
blackberry ||
bb10 ||
(chrome && ua.match(/Android/)) ||
(chrome && ua.match(/CriOS\/([\d.]+)/)) ||
(firefox && ua.match(/Mobile/)) ||
(ie && ua.match(/Touch/)))
);
return { os, browser };
}
使用的時候,
// 把detect 函數引入需要使用的地方
import { detect } from "@/utils/index";
//.....省略
let res = detect(navigator);
console.log(res); // {os: {iphone: true, ios: true, version: "11.0", tablet: false, phone: true}, browser: {webkit: true, version: "604.1.38", safari: true}}
},
具體使用方式,大家可以自定義了。
我在測試中,遇到的問題,是,在自己開發的App中,使用的是webview加載頁面,無法判斷是不是webview,打印出來navigator.userAgent
和在小米手機自帶的瀏覽器中的,是一模一樣的,根本就無法判斷是不是在app中通過webview打開的。
這個也不難理解,他們的瀏覽器,也是套了一個webview的殼而已。
那如何解決,是不是用app內打開的呢?
讓安卓開發人員,在開發的時候,添加一些標誌信息到userAgent
中去吧。
// 修改ua使得web端正確判斷
String ua = webview.getSettings().getUserAgentString();
webview.getSettings().setUserAgentString(ua+"; MYAPP/"+appversion);
具體鏈接可以參考:http://www.jincon.com/archives/354/
然後,我們把這個標籤信息,添加到我們上面寫的判斷中去。微信瀏覽器不就是加了MicroMessenger
這個標誌麼。原理一樣。