WHAT - 前端跨端识别

一、概述

在现代前端开发中,确实需要处理各种终端和系统的兼容性。在 stack overflow 也有一个相关的问题:How to detect Safari, Chrome, IE, Firefox and Opera browsers?

里面采用的回答里有如下 demo:

// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';

// Safari 3.0+ "[object HTMLElementConstructor]" 
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && window['safari'].pushNotification));

// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;

// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;

// Chrome 1 - 79
var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);

// Edge (based on chromium) detection
var isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);

// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;


var output = 'Detecting browsers by ducktyping:<hr>';
output += 'isFirefox: ' + isFirefox + '<br>';
output += 'isChrome: ' + isChrome + '<br>';
output += 'isSafari: ' + isSafari + '<br>';
output += 'isOpera: ' + isOpera + '<br>';
output += 'isIE: ' + isIE + '<br>';
output += 'isEdge: ' + isEdge + '<br>';
output += 'isEdgeChromium: ' + isEdgeChromium + '<br>';
output += 'isBlink: ' + isBlink + '<br>';
document.body.innerHTML = output;

有关 “为什么要特地识别 isBlink?” 的内容可以跳转阅读 WHAT - Blink 浏览器引擎

为了有效地识别当前的终端或系统,你可以使用以下几种方法:

1. User-Agent 字符串

MDN - User-Agent

浏览器会在请求头中发送一个 User-Agent 字符串,其中包含了关于操作系统、浏览器版本和设备类型的信息。你可以通过 JavaScript 访问这个字符串,并解析其中的信息来确定用户的终端或系统。

const userAgent = navigator.userAgent;
// desktop 示例
// 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36'
// mobile 示例
// 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'

if (/mobile/i.test(userAgent)) {
    console.log('Mobile device');
} else if (/tablet/i.test(userAgent)) {
    console.log('Tablet device');
} else {
    console.log('Desktop device');
}

不过,User-Agent 字符串有时可能会被篡改,因此不应完全依赖于它。更多介绍阅读后文中拓展内容。

2. CSS 媒体查询

CSS 媒体查询可以帮助你根据不同的终端特性(如屏幕宽度、高度、分辨率等)应用不同的样式。虽然这不会直接告诉你系统类型,但可以根据样式来间接处理兼容性问题。

/* 针对小屏幕设备 */
@media only screen and (max-width: 600px) {
    body {
        background-color: lightblue;
    }
}

/* 针对大屏幕设备 */
@media only screen and (min-width: 601px) {
    body {
        background-color: lightgreen;
    }
}

3. JavaScript 检测功能

有时候,你需要检测设备的功能特性,而不仅仅是终端类型。例如,检测触控功能、视网膜显示屏等:

// 检测触控设备
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;

// 检测视网膜显示屏
const isRetina = window.devicePixelRatio > 1;

console.log(`Touch device: ${isTouchDevice}`);
console.log(`Retina display: ${isRetina}`);

4. 第三方库

可以使用一些专门的第三方库来帮助你处理设备和浏览器的检测。例如:

  • Bowser: 一个现代的、用于检测浏览器和操作系统的库。
import Bowser from "bowser";

const browser = Bowser.getParser(window.navigator.userAgent);
const result = browser.getResult();

console.log(result);
  • Modernizr: 用于检测浏览器是否支持某些特性,这对于处理兼容性问题很有帮助。
if (Modernizr.touch) {
    console.log('Touch device');
}

总结

这些方法可以帮助你识别终端或系统,但通常会结合使用。比如,你可能会用 User-Agent 来做初步判断,然后用 CSS 媒体查询和 JavaScript 功能检测来处理更细致的兼容性问题。这样可以确保你对不同终端的支持更加全面和准确。

二、拓展

1. User-Agent 篡改

User-Agent 字符串确实有可能被篡改,这可能会影响你的检测结果。以下是一些关于 User-Agent 字符串篡改和其对前端开发影响的详细说明:

User-Agent 字符串篡改的情况

  1. 浏览器插件:一些浏览器插件可以更改 User-Agent 字符串以模仿不同的浏览器或设备,通常用于测试或隐私保护。

  2. 开发者工具:浏览器的开发者工具允许开发者手动更改 User-Agent 字符串进行测试。

  3. 恶意软件:一些恶意软件可能会篡改 User-Agent 字符串以规避检测。

  4. 代理服务器:一些代理服务器可能会修改 User-Agent 字符串以提供不同的内容或功能。

应对策略

由于 User-Agent 字符串可能会被篡改,因此不应完全依赖它。可以结合以下方法提高兼容性和检测准确性:

  1. 多种检测方法结合使用

    • 使用 User-Agent 进行初步检测,但结合 CSS 媒体查询和 JavaScript 特性检测来做进一步的验证。例如,可以使用 User-Agent 判断设备类型,然后用 JavaScript 检测触控支持、分辨率等功能来确认设备的实际能力。
  2. 功能检测

    • 检查浏览器是否支持特定的功能或 API,而不是依赖于 User-Agent 字符串。例如,使用 Modernizr 进行功能检测。示例:检测浏览器是否支持 WebP 图片格式,而不是依赖于 User-Agent 字符串。
const img = new Image();
img.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4IBgAAAD4AAAAvAAAAIAAADgAgAAABzT/VAQAAAAAA==';
img.onload = img.onerror = function() {
    if (img.height === 2) {
        console.log('WebP supported');
    } else {
        console.log('WebP not supported');
    }
};
  1. 服务器端检测

    • 在服务器端进行用户代理分析,可能会更安全,但仍需谨慎,因为客户端的篡改行为可能影响服务器端的判断。
  2. 定期更新

    • 保持对 User-Agent 字符串格式和常见浏览器行为的更新,以便适应新的浏览器和设备变化。
  3. 用户体验优先

    • 在开发过程中,重点关注用户体验和功能的适配,而不仅仅是依赖于设备或浏览器的特定特征。

结论

User-Agent 字符串虽然有助于初步识别用户的设备和浏览器,但由于可能被篡改,你应该结合其他方法进行检测和适配。使用多种检测手段可以提高应用的兼容性和稳定性,从而提供更好的用户体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值