-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbrowser-detection.html
151 lines (141 loc) · 7.46 KB
/
browser-detection.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Fe by idododu</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
</head>
<body>
<section class="page-header">
<h1 class="project-name">浏览器检测(Browser detection)</h1>
<h2 class="project-tagline">总结一下浏览器检测的知识</h2>
</section>
<section class="main-content">
<h3>本文缘由</h3>
<p>工作中需要识别IE 11 与 Edge浏览器做出相应处理,框架中原先写的识别器不支持,现在将实现过程中发现的知识整理如下,以备查验。</p>
<h3>为什么要进行浏览器检测</h3>
<ul>
<li>系统不支持某些浏览器(eg: old ie),如果访问设备为不支持的浏览器,系统需要给出用户提示信息</li>
<li>浏览器对某些功能不支持,对这些浏览器要做特殊处理</li>
<li>访问设备统计</li>
<li>对于不同的设备(device)做不同的处理</li>
</ul>
<p>这里特别要注意第二点, 在所有我读到的关于浏览器检测的文章或者stackoverflow问题中,都会提到一句话:<br>Only use the browser detection method if it's truly necessary, such as showing browser-specific instructions to install an extension. <br>Use feature detection when possible.<br>
只在必要的地方才通过检测浏览器名字与版本号来处理业务逻辑, 当你的疑问句是“if 浏览器不支持 xxx 功能时, do yyy”时,我们需要的是特性检测(feature detection)而不是浏览器检测。<br>分析了一下,原因可能有以下几方面:
</p>
<ul>
<li>UA识别不靠谱,用户可以设置假的useragent string</li>
<li>浏览器升级可能会影响if语句中的判断条件,比如说if(!ie) //init webRTC, 但是某一天ie升级了,支持webRTC了, 这里的判断条件就要改为if(!(ie && ie.version < n)). 相比起来如果用if(!modernizr.webRTC)就不用考虑这么多</li>
<li>浏览器供应厂商太多,有可能要写很多浏览器的名字,比如刚开始说ie 和opera不支持webRTC要做条件区分,我们这样写if(!(ie || opera)) // init webRTC,过两天新出了俩浏览器,这里的条件又要改if(!(ie || opera || uc || tencent)) // init webRTC, 相比起来if(!modernizr.webRTC)就不用考虑这么多</li>
</ul>
<h3>如何实现浏览器检测</h3>
<ul>
<li>用正则表达式解析userAgent字符串, 提取环境信息 <br>关于userAgent推荐NCZ大神的两篇文章<br><a href="https://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/">History of the user-agent string</a><br><a href="https://www.nczonline.net/blog/2013/03/27/internet-explorer-11s-user-agent-string-what-does-it-mean/">nternet Explorer 11′s user-agent string</a><br>还有<a href="http://www.w3school.com.cn/jsref/dom_obj_navigator.asp">w3cschool的手册: Navigator对象</a></li>
<li>使用浏览器特殊属性来判断,比如IE下的StyleMedia属性, firefox的InstallerTrigger, chrome的chrome.webstore对象</li>
<li>IE浏览器可以用微软的私有属性条件注释(conditional comments)来识别<br>
<pre><!–[if IE]> Only IE <![endif]–>
<!–[if IE 5.0]> Only IE 5.0 <![endif]–>
<!–[if gt IE 5.0]> Only IE 5.0+ <![endif]–>
<!–[if lt IE 6]> Only IE 6- <![endif]–>
<!–[if gte IE 6]> Only IE 6/+ <![endif]–>
<!–[if lte IE 7]> Only IE 7/- <![endif]–></pre>
</li>
<li>服务器端解析,如php下的<a href="https://github.com/WhichBrowser/Parser">whichbrowser</a></li>
</ul>
<p>比较流行的做法是解析userAgent字符串,因为:<br>1. 使用浏览器特殊属性判断无法获取浏览器版本号,设备类型,操作系统等参数<br>2. 服务器端解析又觉得大材小用,能前端搞定的,何必求爷爷告奶奶地找后端开发呢?</p>
<h3>浏览器检测开源类库比较</h3>
<p>作为一个github代码的搬运工,我觉得该出手了</p>
<table>
<thead>
<tr>
<th> </th>
<th><a href="https://github.com/darcyclarke/Detect.js">detect.js</a></th>
<th><a href="https://github.com/ded/bowser">bowser.js</a></th>
<th><a href="is.js.org">is.js</a></th>
<th><a href="http://api.jquery.com/jQuery.browser/">$.browser</a></th>
</tr>
</thead>
<tr>
<td>识别浏览器类型</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>识别浏览器版本号</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
<td>N</td>
</tr>
<tr>
<td>识别操作系统(Win, ios, android, linux)</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>识别设备类型(mobile, tablet, desktop)</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>github stars</td>
<td>430</td>
<td>1542</td>
<td>7414</td>
<td>NA</td>
</tr>
<tr>
<td>最近更新(2016.08.03)</td>
<td>2016.06.03</td>
<td>2016.07.27</td>
<td>2016.06.05</td>
<td>NA</td>
</tr>
<tr>
<td>未解决issue</td>
<td>11</td>
<td>10</td>
<td>5</td>
<td>NA</td>
</tr>
<tr>
<td>文件大小</td>
<td>未压缩49.5kb, <br>压缩25.6kb</td>
<td>未压缩15.7kb</td>
<td>未压缩32.9 KB,<br>压缩13.9kb</td>
<td>NA</td>
</tr>
<tr>
<td>其他优点</td>
<td>可以自定义功能</td>
<td></td>
<td>提供了强大的判断功能(类型,正则,运算, 环境,时间...)</td>
<td></td>
</tr>
<tr>
<td>其他缺点</td>
<td></td>
<td></td>
<td>不支持模块化,无法自定义功能,全部引入后会与系统一些功能重复</td>
<td>1.9版本后已移除$.browser,<br>推荐使用modernizr</td>
</tr>
</table>
<h4><a href="https://modernizr.com/">Modernizr</a></h4>
<p>通过检测浏览器是否支持某些特性,并在html节点上增加特定class来标识;<br>可以扩展自定义的规则;<br>可以自定义需要的功能</p>
<footer class="site-footer">
<span class="site-footer-owner"><a href="https://github.com/idododu/FE">Fe</a> is maintained by <a href="https://github.com/idododu">idododu</a>.</span>
<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>
</section>
</body>
</html>