前端如何判断浏览器类型及版本?

5,991 阅读4分钟

 持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

前言

在网站前端开发中,浏览器兼容性问题让我们手忙脚乱,浏览器兼容性是前端开发框架要解决的第一个问题,要解决兼容性问题就得首先准确判断出浏览器的类型及其版本。

JavaScript是前端开发的主要语言,我们可以通过编写JavaScript程序来判断浏览器的类型及版本。

获取浏览器类型及版本信息

JavaScript判断浏览器类型一般有两种办法:一种是根据各种浏览器独有的属性来分辨;另一种是通过分析浏览器的userAgent属性来判断的。

在许多情况下,判断出浏览器类型之后,还需判断浏览器版本才能处理兼容性问题,而判断浏览器的版本一般只能通过分析浏览器的userAgent才能知道。

思路: 我们可以通过BOM中navigator对象的userAgent属性来获取浏览器的信息,然后根据各个浏览器所独有的信息来判断用户使用的是哪种浏览器

以谷歌浏览器为例,在控制台打印navigator.userAgent为:

Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36

在以上给出的信息中可以根据关键字Chrome来判断用户使用的为谷歌浏览器,并且,版本号为Chrome之后的数字。其他浏览器也可通过此方法来获悉,下面给出获取浏览器类型及版本的完整代码示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      function browserinfo() {
        var Browser_Name = navigator.appName;
        var Browser_Version = parseFloat(navigator.appVersion);
        var Browser_Agent = navigator.userAgent;
        var Actual_Version, Actual_Name;
        // var is_IE = Browser_Name == "Microsoft Internet Explorer";
        //判读是否为ie浏览器,ie浏览器已废弃,无需兼容
        var is_NN = Browser_Name == "Netscape"; //判断是否为netscape浏览器
        var is_op = Browser_Name == "Opera"; //判断是否为Opera浏览器
        if (is_NN) {
          //appName为'Netscape'的浏览器可能为Chrome、Firefox、Edge等
          //处理5.0及以上版本
          if (Browser_Version >= 5.0) {
            if (Browser_Agent.indexOf("Netscape") != -1) {
              var Split_Sign = Browser_Agent.lastIndexOf("/");
              var Version = Browser_Agent.lastIndexOf(" ");
              var Bname = Browser_Agent.substring(0, Split_Sign);
              var Split_sign2 = Bname.lastIndexOf(" ");
              Actual_Version = Browser_Agent.substring(
                Split_Sign + 1,
                Browser_Agent.length
              );
              Actual_Name = Bname.substring(Split_sign2 + 1, Bname.length);
            }
            if (Browser_Agent.indexOf("Firefox") != -1) {
              //火狐浏览器具有Firefox唯一标识
              var Split_Sign = Browser_Agent.lastIndexOf("/");
              var Version = Browser_Agent.lastIndexOf(" ");
              Actual_Version = Browser_Agent.substring(
                Split_Sign + 1,
                Browser_Agent.length
              );
              Actual_Name = Browser_Agent.substring(Version + 1, Split_Sign);
            }
            if (Browser_Agent.indexOf("Safari") != -1) {
              //Chrome、Edge和Safari浏览器appName都有Safari字段
              if (Browser_Agent.indexOf("Chrome") != -1) {
                //Chrome和Edge浏览器appName都有Chrome字段
                //Chrome浏览器
                var Split_Sign = Browser_Agent.lastIndexOf(" ");
                var Version = Browser_Agent.substring(0, Split_Sign);
                var Split_Sign2 = Version.lastIndexOf("/");
                var Bname = Version.lastIndexOf(" ");
                Actual_Version = Version.substring(
                  Split_Sign2 + 1,
                  Version.length
                );
                Actual_Name = Version.substring(Bname + 1, Split_Sign2);
                if (Browser_Agent.indexOf("Edg") != -1) {
                  //为Edge浏览器
                  var Split_Sign = Browser_Agent.lastIndexOf("/");
                  var Version = Browser_Agent.substring(0, Split_Sign);
                  var Split_Sign2 = Browser_Agent.lastIndexOf("/");
                  var Bname = Browser_Agent.lastIndexOf(" ");
                  console.log("Bname:", Bname);
                  Actual_Version = Browser_Agent.substring(
                    Split_Sign2 + 1,
                    Browser_Agent.length
                  );
                  Actual_Name = Browser_Agent.substring(Bname + 1, Split_Sign);
                }
              } else {
                //Safari浏览器
                var Split_Sign = Browser_Agent.lastIndexOf("/");
                var Version = Browser_Agent.substring(0, Split_Sign);
                var Split_Sign2 = Version.lastIndexOf("/");
                var Bname = Browser_Agent.lastIndexOf(" ");
                Actual_Version = Browser_Agent.substring(
                  Split_Sign2 + 1,
                  Bname
                );
                Actual_Name = Browser_Agent.substring(Bname + 1, Split_Sign);
              }
            }
          } else {
            Actual_Version = Browser_Version;
            Actual_Name = Browser_Name;
          }
        }
        //  else if (is_IE) {
        //   var Version_Start = Browser_Agent.indexOf("MSIE");
        //   var Version_End = Browser_Agent.indexOf(";", Version_Start);
        //   Actual_Version = Browser_Agent.substring(
        //     Version_Start + 5,
        //     Version_End
        //   );
        //   Actual_Name = Browser_Name;
        //   if (
        //     Browser_Agent.indexOf("Maxthon") != -1 ||
        //     Browser_Agent.indexOf("MAXTHON") != -1
        //   ) {
        //     var mv = Browser_Agent.lastIndexOf(" ");
        //     var mv1 = Browser_Agent.substring(mv, Browser_Agent.length - 1);
        //     mv1 = "遨游版本:" + mv1;
        //     Actual_Name += "(Maxthon)";
        //     Actual_Version += mv1;
        //   }
        // }
        else if (is_op) {
          //Opera浏览器
          Actual_Name = "Opera";
          var tempstart = Browser_Agent.indexOf("Opera");
          var tempend = Browser_Agent.length;
          Actual_Version = Browser_Version;
        } else {
          Actual_Name = "Unknown Navigator";
          Actual_Version = "Unknown Version";
        }
        //将获取的浏览器名称以及版本号存储在navigator对象上
        navigator.Actual_Name = Actual_Name;
        navigator.Actual_Version = Actual_Version;
        this.Name = Actual_Name;
        this.Version = Actual_Version;
      }
      browserinfo(); //调用刚刚定义的函数
      document.write("你使用的浏览器是:" + navigator.userAgent);
      document.write("<br>");
      document.write(
        "你使用的浏览器是:" +
          navigator.Actual_Name +
          ",版本号:" +
          navigator.Actual_Version
      );
    </script>
  </body>
</html>

上面代码看起来特别繁琐,通过利用正则表达式,我们可以用更少的代码实现该功能:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" />
    <script>
      var Sys = {};
      var ua = navigator.userAgent.toLowerCase();
      var s;
      (s = ua.match(/edg/([\d.]+)/))
        ? (Sys.edg = 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;
      //以下进行测试
      if (Sys.edg) document.write("Edge: " + Sys.edg);
      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);
    </script>
  </body>
</html>

思路: 以上代码采用了“... ? ... : ...”这样的判断表达式来精简代码。判断条件是一条赋值语句,既完成正则表达式的匹配及结果复制,又直接作为条件判断。而随后的版本信息只需从前面的匹配结果中提取即可,这是非常高效的代码。 

好了,以上就是获取浏览器的方法了,在上述方法中用到了BOM中的navigator对象,但是,你真的已经非常了解这个对象了吗?下面介绍一下该对象的一些属性和API

BOM之navigator

navigator对象包含有关浏览器的信息,通过该对象可以来识别不同的浏览器,最常用的就是userAgent,该属性可以返回由客户端发送服务器的user-agent头部的值

由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了,一般我们只会使用userAgent来判断浏览器的信息,userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent

属性或方法说明
appCodeName浏览器名称。通常是Mozilla
appName完整的浏览器名称
appMinorVersion次版本信息
appVersion浏览器的版本。一般不与实际的浏览器版本对应
buildID浏览器编译版本
cookieEnabled表示cookie是否启用
cpuClass客户端计算机中使用的CPU类型(x86,68K,Alpha,PPC或Other)
javaEnabled()表示当前浏览器中是否启用Java
language浏览器的住语言
mimeTypes在浏览器中注册的MIME类型数组
onLine表示浏览器是否连接到了因特网
Platform浏览器所在的系统平台
plugins浏览器中安装的插件信息的数组
userAgent浏览器的用户代理字符串

检测浏览器安装了哪些插件?

检测浏览器中是否安装了特定的插件

方法:plugins[i];     每个数组成员包含属性:

属性说明
name:插件的名字
description:插件的描述
filename:插件的文件名
length:插件所处理的MIME类型数量

代码示例:(以最新版Chrome浏览器为例)

function hasPlugin(name){
    //转换为小写
    name = name.toLowerCase();
    for(var i = 0; i<navigator.plugins.length; i++){
    // 迭代plugins数组,通过indexof()检测每个name属性
    if(navigator.plugins[i].name.toLowerCase().indexOf(name)>-1){
            return true;
        }
    }
    return false;
}
//检测Flash
console.log(hasPlugin("Flash"));// false

//检测QuickTime
console.log(hasPlugin("QuickTime"));//false