浏览器版本兼容问题很常见,这里记录下近期踩的坑:在nuxt 项目中,如何处理低版本浏览器的不兼容问题。
问题描述
网页在chrome 75 及 Safari 12 中均可以正常显示,但对 360安全浏览器 8.1版本的支持并不友好,360中存在的主要问题是上下滚动条消失,鉴于360 8.1 版本的浏览器使用的内核是 chrome 45,故 下载了chrome 45 测试,发现chrome 45 也存在相同的问题,故问题转变为 如何处理内核 为chrome 45- 的浏览器不兼容问题。
解决方法
最直接的方式:通过 userAgent 判断浏览器类型及版本,然后针对不兼容的低版本浏览器,显示页面,提示用户进行版本升级或者更换其他的浏览器。
思路没有问题,网上也搜出来了一堆判断浏览器类型及版本的示例代码,但这些处理方式的基本思路是先判断浏览器类型,然后判断版本,而这里需要处理的是 内核 为chrome的浏览器,可能是chrome,可能是360, 也可能是opera,只要版本低于45,则要求升级或更换。故,首先得去解析userAgent。
User Agent mozilla 中给出了UA的基本组成 以及 主流浏览器的UA 字符串:
Web端 User -Agent 基本组成规则:
Mozilla/<version> (<system-information>) <platform> (<platform-details>) <extensions>
部分主流浏览器的UA示例:「在 常用浏览器(PC,移动) user-agent 可以查到 UC,腾讯TT等部分国内浏览器的UA。」
Chrome
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Firefox
Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0
Opera
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 OPR/38.0.2220.41
Safari
Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1
IE
Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)
根据UA 的基本组成规则,可以考虑解析整个UA,分成三部分:
Mozilla/<version> (<system-information>)
<platform> (<platform-details>)
<extensions>
部分浏览器可能仅有第一部分,比如IE,这样可以根据 system-information 来判断是否为IE,并获取其版本,而针对chrome 部分,在解析得到的extensions 中进行二次解析,先根据空白符分割成数组,再针对数组中的每一个对象,进行split(‘/‘),取到每一个extension的name 和version,最后只需要判断chrome 是否存在该数组中,存在则取其对应version,判断version是否过低即可。
具体的解析代码这里就不列出来了。
另一个需要说明的地方,是让这段处理浏览器不兼容的代码具有可扩展性。
比如这次处理的是chrome 45 以下版本,下一次如果发现腾讯TT 4.0 以下版本存在不兼容问题,需要在不修改主代码的情况下,保证功能正常。
鉴于自己写得很烂,这里直接借用领导的处理方式:
新建变量blacklist,将所有不兼容的浏览器,版本及规则放入blacklist中。
新建class AgentInfo,在AgentInfo内部定义extension,test等函数。
使用parseAgentInfo方法,解析 userAgent,将解析后的结果塞给 AgentInfo ,进行初始化,得到AgentInfo的实例。
针对blacklist中的rules,逐一进行测试,如有未通过测试的,则表示该浏览器过低,跳转至新页面,要求用户升级或者更换浏览器。
大致代码如下:
const blacklist = [
{ name: 'chrome <= 45', rules: [
(info) => info.extension('Chrome').versionNumber <= 45
]}
]
export default function ({ route, req, redirect }) {
const userAgent = process.server ? req.headers['user-agent'] : navigator.userAgent
const agentInfo = parseAgentInfo(userAgent)
const uncompatible = _.some(blacklist, (item) => agentInfo.test(item.rules))
if (uncompatible) {
redirect('/compatible')
}
}
后面如果需要排除其他不兼容的浏览器,只需更改blacklist即可。
这部分是中间件的内容,不要忘记在nuxt.config.js
中声明对应的文件名。