browser-type.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * @description 获取用户浏览器版本及系统信息
  3. * @param {string='zh-cn' | 'en'} lang 返回中文的信息还是英文的
  4. * @constructor
  5. */
  6. export default function BrowserType(lang: 'zh-cn' | 'en' = 'en') {
  7. // 权重:系统 + 系统版本 > 平台 > 内核 + 载体 + 内核版本 + 载体版本 > 外壳 + 外壳版本
  8. const ua = navigator.userAgent.toLowerCase();
  9. const testUa = (regexp: any) => regexp.test(ua);
  10. const testVs = (regexp: any) =>
  11. ua
  12. .match(regexp)
  13. ?.toString()
  14. .replace(/[^0-9|_.]/g, '')
  15. .replace(/_/g, '.');
  16. // 系统
  17. const system =
  18. new Map([
  19. [testUa(/windows|win32|win64|wow32|wow64/g), 'windows'], // windows系统
  20. [testUa(/macintosh|macintel/g), 'macos'], // macos系统
  21. [testUa(/x11/g), 'linux'], // linux系统
  22. [testUa(/android|adr/g), 'android'], // android系统
  23. [testUa(/ios|iphone|ipad|ipod|iwatch/g), 'ios'], // ios系统
  24. ]).get(true) || 'unknow';
  25. // 系统版本
  26. const systemVs =
  27. new Map([
  28. [
  29. 'windows',
  30. new Map([
  31. [testUa(/windows nt 5.0|windows 2000/g), '2000'],
  32. [testUa(/windows nt 5.1|windows xp/g), 'xp'],
  33. [testUa(/windows nt 5.2|windows 2003/g), '2003'],
  34. [testUa(/windows nt 6.0|windows vista/g), 'vista'],
  35. [testUa(/windows nt 6.1|windows 7/g), '7'],
  36. [testUa(/windows nt 6.2|windows 8/g), '8'],
  37. [testUa(/windows nt 6.3|windows 8.1/g), '8.1'],
  38. [testUa(/windows nt 10.0|windows 10/g), '10'],
  39. ]).get(true),
  40. ],
  41. ['macos', testVs(/os x [\d._]+/g)],
  42. ['android', testVs(/android [\d._]+/g)],
  43. ['ios', testVs(/os [\d._]+/g)],
  44. ]).get(system) || 'unknow';
  45. // 平台
  46. let platform = 'unknow';
  47. if (system === 'windows' || system === 'macos' || system === 'linux') {
  48. platform = 'desktop'; // 桌面端
  49. } else if (system === 'android' || system === 'ios' || testUa(/mobile/g)) {
  50. platform = 'mobile'; // 移动端
  51. }
  52. // 内核和载体
  53. const [engine = 'unknow', supporter = 'unknow'] = new Map([
  54. [
  55. testUa(/applewebkit/g),
  56. [
  57. 'webkit',
  58. new Map([
  59. // webkit内核
  60. [testUa(/safari/g), 'safari'], // safari浏览器
  61. [testUa(/chrome/g), 'chrome'], // chrome浏览器
  62. [testUa(/opr/g), 'opera'], // opera浏览器
  63. [testUa(/edge/g), 'edge'], // edge浏览器
  64. ]).get(true),
  65. ] || 'unknow',
  66. ], // [webkit内核, xxx浏览器]
  67. [testUa(/gecko/g) && testUa(/firefox/g), ['gecko', 'firefox']], // [gecko内核,firefox浏览器]
  68. [testUa(/presto/g), ['presto', 'opera']], // [presto内核,opera浏览器]
  69. [testUa(/trident|compatible|msie/g), ['trident', 'iexplore']], // [trident内核,iexplore浏览器]
  70. ]).get(true) || ['unknow', 'unknow'];
  71. // 内核版本
  72. const engineVs =
  73. new Map([
  74. ['webkit', testVs(/applewebkit\/[\d._]+/g)],
  75. ['gecko', testVs(/gecko\/[\d._]+/g)],
  76. ['presto', testVs(/presto\/[\d._]+/g)],
  77. ['trident', testVs(/trident\/[\d._]+/g)],
  78. ]).get(engine) || 'unknow';
  79. // 载体版本
  80. const supporterVs =
  81. new Map([
  82. ['firefox', testVs(/firefox\/[\d._]+/g)],
  83. ['opera', testVs(/opr\/[\d._]+/g)],
  84. ['iexplore', testVs(/(msie [\d._]+)|(rv:[\d._]+)/g)],
  85. ['edge', testVs(/edge\/[\d._]+/g)],
  86. ['safari', testVs(/version\/[\d._]+/g)],
  87. ['chrome', testVs(/chrome\/[\d._]+/g)],
  88. ]).get(supporter) || 'unknow';
  89. // 外壳和外壳版本
  90. const [shell = 'none', shellVs = 'unknow'] = new Map([
  91. [testUa(/micromessenger/g), ['wechat', testVs(/micromessenger\/[\d._]+/g)]], // [微信浏览器,]
  92. [testUa(/qqbrowser/g), ['qq', testVs(/qqbrowser\/[\d._]+/g)]], // [QQ浏览器,]
  93. [testUa(/ucbrowser/g), ['uc', testVs(/ucbrowser\/[\d._]+/g)]], // [UC浏览器,]
  94. [testUa(/qihu 360se/g), ['360', 'unknow']], // [360浏览器(无版本),]
  95. [testUa(/2345explorer/g), ['2345', testVs(/2345explorer\/[\d._]+/g)]], // [2345浏览器,]
  96. [testUa(/metasr/g), ['sougou', 'unknow']], // [搜狗浏览器(无版本),]
  97. [testUa(/lbbrowser/g), ['liebao', 'unknow']], // [猎豹浏览器(无版本),]
  98. [testUa(/maxthon/g), ['maxthon', testVs(/maxthon\/[\d._]+/g)]], // [遨游浏览器,]
  99. ]).get(true) || ['none', 'unknow'];
  100. return {
  101. 'zh-cn': Object.assign(
  102. {
  103. 内核: engine, // 内核: webkit gecko presto trident
  104. 内核版本: engineVs, // 内核版本
  105. 平台: platform, // 平台: desktop mobile
  106. 载体: supporter, // 载体: chrome safari firefox opera iexplore edge
  107. 载体版本: supporterVs, // 载体版本
  108. 系统: system, // 系统: windows macos linux android ios
  109. 系统版本: systemVs, // 系统版本
  110. },
  111. shell === 'none'
  112. ? {}
  113. : {
  114. 外壳: shell, // 外壳: wechat qq uc 360 2345 sougou liebao maxthon
  115. 外壳版本: shellVs, // 外壳版本
  116. }
  117. ),
  118. en: Object.assign(
  119. {
  120. engine, // 内核: webkit gecko presto trident
  121. engineVs, // 内核版本
  122. platform, // 平台: desktop mobile
  123. supporter, // 载体: chrome safari firefox opera iexplore edge
  124. supporterVs, // 载体版本
  125. system, // 系统: windows macos linux android ios
  126. systemVs, // 系统版本
  127. },
  128. shell === 'none'
  129. ? {}
  130. : {
  131. shell, // 外壳: wechat qq uc 360 2345 sougou liebao maxthon
  132. shellVs, // 外壳版本
  133. }
  134. ),
  135. }[lang];
  136. }