JavaScript获取移动设备型号的实现代码(JS获取手机型号和系统)


Posted in Javascript onMarch 10, 2018

我们一般在浏览器里识别用户的访问设备都是通过 User Agent 这个字段来获取的,但是通过它我们只能获取一个大概的信息,比如你用的是 Mac 还是 Windows,用的是 iPhone 还是 iPad。如果我想知道你用的是第几代 iPhone,这个方法就不行了,前段时间我正好有这个需求,识别移动客户端的具体型号(主要是 iOS 设备),于是思考了下这个问题的实现。

首先,我跟大家一样想到了 UA,不过事实证明这路走不通。就在我无聊一个一个摆弄浏览器的 API 时,突然一篇文章里的某段代码提醒了了我。这篇文章讲的是怎样通过 js 获取图形设备信息的,因为 HTML5 支持了 canvas,所以可以通过 API 获取图形设备的型号,比如显卡的型号。

(function () {
  var canvas = document.createElement('canvas'),
    gl = canvas.getContext('experimental-webgl'),
    debugInfo = gl.getExtension('WEBGL_debug_renderer_info');

  console.log(gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL));
})();

运行这段代码就可以获取显卡的型号了,如果你在iOS的设备里运行,会获取到诸如 Apple A9 GPU 之类的信息。而我们知道每一代 iOS 设备的 GPU 型号都是不同的,比如 iPhone 6 是 A8,而 iPhone 6s 就是 A9。看到这里,你应该大概知道我的思路了,就是通过识别 GPU 的型号来辨别设备的型号。

不过这还有个小瑕疵,有些设备是同一代,也就是 GPU 型号完全相同,比如 iPhone 6s, iPhone 6s Plus, iPhone SE。它们用的都是 Apple A9 GPU,怎么区分开它们呢?你会发现它们最大的不同不就是分辨率不同吗?而通过 JavaScript 我们又可以方便地获取屏幕分辨率,这样把两个手段综合应用一下就可以获取设备的准确型号了。

这里有个示例网址,大家可以用手机访问
https://joyqi.github.io/mobile-device-js/example.html

我的代码都放在了 GitHub 上
https://github.com/joyqi/mobile-device-js

这次思考给了我一些解决问题的启发,我们在思考解决方案的时候从侧面入手说不定会有新的发现。就比如我们的这个代码,目前还无法识别同一代的 iPad Air 和 iPad mini,因为它们的 GPU 和分辨率均相同,但是延续这个思路其实是有很多解决方案的,比如大家可以研究下这两个设备的话筒和喇叭个数,而这个数量也是可以通过 JS 获取的 :P

完整的测试代码

<html>
  <head>
    <title>Mobile Device Example</title>
    <script src="./device.js"></script>
  </head>
  <head>
    <h1>GPU: <script>document.write(MobileDevice.getGlRenderer());</script></h1>
    <h1>Device Models: <script>document.write(MobileDevice.getModels().join(' or '));</script></h1>
  </head>
</html>

device.js

(function () {
  var canvas, gl, glRenderer, models,
    devices = {
      "Apple A7 GPU": {
        1136: ["iPhone 5", "iPhone 5s"],
        2048: ["iPad Air", "iPad Mini 2", "iPad Mini 3"]
      },

      "Apple A8 GPU": {
        1136: ["iPod touch (6th generation)"],
        1334: ["iPhone 6"],
        2001: ["iPhone 6 Plus"],
        2048: ["iPad Air 2", "iPad Mini 4"]
      },

      "Apple A9 GPU": {
        1136: ["iPhone SE"],
        1334: ["iPhone 6s"],
        2001: ["iPhone 6s Plus"],
        2224: ["iPad Pro (9.7-inch)"],
        2732: ["iPad Pro (12.9-inch)"]
      },

      "Apple A10 GPU": {
        1334: ["iPhone 7"],
        2001: ["iPhone 7 Plus"]
      }
    };

  function getCanvas() {
    if (canvas == null) {
      canvas = document.createElement('canvas');
    }

    return canvas;
  }

  function getGl() {
    if (gl == null) {
      gl = getCanvas().getContext('experimental-webgl');
    }

    return gl;
  }

  function getScreenWidth() {
    return Math.max(screen.width, screen.height) * (window.devicePixelRatio || 1);
  }

  function getGlRenderer() {
    if (glRenderer == null) {
      debugInfo = getGl().getExtension('WEBGL_debug_renderer_info');
      glRenderer = debugInfo == null ? 'unknown' : getGl().getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
    }

    return glRenderer;
  }

  function getModels() {
    if (models == null) {
      var device = devices[getGlRenderer()];

      if (device == undefined) {
        models = ['unknown'];
      } else {
        models = device[getScreenWidth()];

        if (models == undefined) {
          models = ['unknown'];
        }
      }
    }

    return models;
  }

  if (window.MobileDevice == undefined) {
    window.MobileDevice = {};
  }

  window.MobileDevice.getGlRenderer = getGlRenderer;
  window.MobileDevice.getModels = getModels;
})();

JS获取手机型号和系统

想要通过js获取手机的一些基本参数,就要使用到navigator.userAgent,通过我们可以获取到浏览器的一些基本信息。如果想在页面中看到navigator.userAgent内容,我们可以使用document.write(navigator.userAgent);打印到页面上,可以更清晰的看到具体内容。

1、下面是我打印的一些手机中的userAgent内容:

1、iphone6 plus
Mozilla/5.0 (iPhone; CPU iPhone OS <span style="color:#ff0000;">10_2_1</span> like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Mobile/14D27

iphone7 plus
Mozilla/5.0 (iPhone; CPU iPhone OS <span style="color:#ff0000;">10_3_1</span> like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304

2、魅族
Mozilla/5.0 (Linux; <span style="color:#ff0000;">Android 5.1</span>; <span style="color:#3366ff;">m1 metal</span> Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.127 Mobile Safari/537.36

3、三星
Mozilla/5.0 (Linux; <span style="color:#ff0000;">Android 6.0.1</span>; <span style="color:#3366ff;">SM-A8000</span> Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36

4、小米
Mozilla/5.0 (Linux; <span style="color:#ff0000;">Android 6.0.1</span>; <span style="color:#3366ff;">Redmi Note 4X</span> Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36

从上面我们可以看出iphone的里面都含有iPhone字段,系统版本字段为上面标红的地方。2、3、4是几款Android手机的userAgent内容,仔细观察不难发现Android 5.1等就是系统版本。而蓝色的就是手机型号。至于其他内容,包含浏览器版本等,这里不做解释。如果想知道这个userAgent内容的具体含义和来源可以参考如下地址查看具体解释:

为什么所有浏览器的userAgent都带Mozilla

2、在网上查了下有木有现成的js能直接实现此功能,找到了一个mobile-detect.js。基本可以实现我们需要的参数,下载地址:

https://github.com/hgoebl/mobile-detect.js/

文档地址:

http://hgoebl.github.io/mobile-detect.js/doc/MobileDetect.html

使用方法:

var md = new MobileDetect( 
  'Mozilla/5.0 (Linux; U; Android 4.0.3; en-in; SonyEricssonMT11i' + 
  ' Build/4.1.A.0.562) AppleWebKit/534.30 (KHTML, like Gecko)' + 
  ' Version/4.0 Mobile Safari/534.30'); 
 
// more typically we would instantiate with 'window.navigator.userAgent' 
// as user-agent; this string literal is only for better understanding 
 
console.log( md.mobile() );     // 'Sony' 
console.log( md.phone() );      // 'Sony' 
console.log( md.tablet() );     // null 
console.log( md.userAgent() );    // 'Safari' 
console.log( md.os() );       // 'AndroidOS' 
console.log( md.is('iPhone') );   // false 
console.log( md.is('bot') );     // false 
console.log( md.version('Webkit') );     // 534.3 
console.log( md.versionStr('Build') );    // '4.1.A.0.562' 
console.log( md.match('playstation|xbox') ); // false

使用过程中ios没有什么问题,想获取的都可以获取到,不过Android并不是都能获取到。所以又对Android的做了单独处理。发现Android手机型号后面都带了一段Build/...。所以就以此做了下单独处理,来获取Android手机型号。下面是具体代码:

<!DOCTYPE html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<meta name="viewport" 
  content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no"> 
<title>JS获取手机型号和系统</title> 
</head> 
<body> 
</body> 
<script src="js/lib/jquery-1.11.1.min.js"></script> 
<script src="js/lib/mobile-detect.min.js"></script> 
<script> 
  //判断数组中是否包含某字符串 
  Array.prototype.contains = function(needle) { 
    for (i in this) { 
      if (this[i].indexOf(needle) > 0) 
        return i; 
    } 
    return -1; 
  } 
 
  var device_type = navigator.userAgent;//获取userAgent信息 
  document.write(device_type);//打印到页面 
  var md = new MobileDetect(device_type);//初始化mobile-detect 
  var os = md.os();//获取系统 
  var model = ""; 
  if (os == "iOS") {//ios系统的处理 
    os = md.os() + md.version("iPhone"); 
    model = md.mobile(); 
  } else if (os == "AndroidOS") {//Android系统的处理 
    os = md.os() + md.version("Android"); 
    var sss = device_type.split(";"); 
    var i = sss.contains("Build/"); 
    if (i > -1) { 
      model = sss[i].substring(0, sss[i].indexOf("Build/")); 
    } 
  } 
  alert(os + "---" + model);//打印系统版本和手机型号 
</script> 
</html>

得到结果:

iphone iOS10.21---iPhone

android AndroidOS6.01---Redmi Note 4X

Javascript 相关文章推荐
JS模拟多线程
Feb 07 Javascript
javascript中的循环语句for语句深入理解
Apr 04 Javascript
JavaScript设计模式之抽象工厂模式介绍
Dec 28 Javascript
javascript省市级联功能实现方法实例详解
Oct 20 Javascript
JavaScript基础——使用Canvas绘图
Nov 02 Javascript
jQuery Jsonp跨域模拟搜索引擎
Jun 17 jQuery
微信小程序使用modal组件弹出对话框功能示例
Nov 29 Javascript
echarts同一页面中四个图表切换的js数据交互方法示例
Jul 03 Javascript
ES6的Fetch异步请求的实现方法
Dec 07 Javascript
nest.js 使用express需要提供多个静态目录的操作方法
Oct 24 Javascript
React学习之受控组件与数据共享实例分析
Jan 06 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 Javascript
js经验分享 JavaScript反调试技巧
Mar 10 #Javascript
webpack打包node.js后端项目的方法
Mar 10 #Javascript
webpack external模块的具体使用
Mar 10 #Javascript
webpack组织模块打包Library的原理及实现
Mar 10 #Javascript
浅谈webpack组织模块的原理
Mar 10 #Javascript
Vuex实现计数器以及列表展示效果
Mar 10 #Javascript
在vue中使用css modules替代scroped的方法
Mar 10 #Javascript
You might like
过滤掉PHP数组中的重复值的实现代码
2011/07/17 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
php实现格式化多行文本为Js可用格式
2015/04/15 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
在js中单选框和复选框获取值的方式
2009/11/06 Javascript
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
JQuery AJAX 中文乱码问题解决
2013/06/05 Javascript
JQuery调用WebServices的方法和4个实例
2014/05/06 Javascript
javascript 中的console.log和弹出窗口alert
2016/08/30 Javascript
jquery控制页面的展开和隐藏实现方法(推荐)
2016/10/15 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
Vue computed计算属性的使用方法
2017/07/14 Javascript
jQuery.Sumoselect插件实现下拉复选框效果
2017/11/09 jQuery
vue编译打包本地查看index文件的方法
2018/02/23 Javascript
详解vue axios二次封装
2018/07/22 Javascript
送你43道JS面试题(收藏)
2019/06/17 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
VUE+node(express)实现前后端分离
2019/10/13 Javascript
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
python操作MySQL数据库的方法分享
2012/05/29 Python
基于python元祖与字典与集合的粗浅认识
2017/08/23 Python
django中上传图片分页三级联动效果的实现代码
2019/08/30 Python
Python对称的二叉树多种思路实现方法
2020/02/28 Python
Python进行统计建模
2020/08/10 Python
html5.2 dialog简介详解
2018/02/27 HTML / CSS
购买瑞典当代设计的腕表和太阳眼镜:TRIWA
2016/10/30 全球购物
Jimmy Choo美国官网:周仰杰鞋子品牌
2018/06/08 全球购物
英国游戏机和游戏购物网站:365games.co.uk
2018/06/18 全球购物
汽车驾驶求职信
2013/10/25 职场文书
校园招聘策划书
2014/01/09 职场文书
秋季婚礼证婚词
2014/01/11 职场文书
2014年教师工作总结
2014/11/10 职场文书
2014年财务个人工作总结
2014/12/08 职场文书
小学思想品德教学反思
2016/02/24 职场文书
详解Redis瘦身指南
2021/05/26 Redis
使用CSS3实现按钮悬停闪烁动态特效代码
2021/08/30 HTML / CSS