应优先运行时检测HTML5特性而非依赖DOCTYPE或UA判断,如localStorage、history.pushState、canvas.getContext等,并用Modernizr定制构建;服务端UA仅作简单资源降级,真实用户监控更有效。
直接看浏览器是否支持关键 HTML5 API,而不是查文档或看 DOCTYPE—— 本身不保证兼容性,只声明解析模式。
最可靠的方式是运行时检测(feature detection),而非 UA 判断。现代网站应优先检查 localStorage、history.pushState、querySelector、canvas.getContext 等实际用到的 API。
typeof localStorage !== 'undefined' —— 注意 Safari 无痕模式下会抛异常,需 try/catch 包裹typeof history.pushState === 'function' —— IE9 及以下返回 undefined,但部分 IE10+ 移动版有 bugdocument.createElement('canvas').getContext —— 返回 function 才算真正支持 canvas 渲染'ontouchstart' in window 或 !!window.
TouchEvent —— 区分触控能力,不是所有 HTML5 浏览器都支持 touch 事件Modernizr 的默认全量检测Modernizr 是工具,不是标准。它生成的 modernizr.js 默认检测上百项,但多数项目只用其中几项。盲目引入会拖慢首屏,且某些检测(如 input[type="date"])在 Chrome 中返回 true,实际体验却因系统级日历缺失而降级。
websockets、flexbox、audio) class 上(如 no-flexbox),CSS 中用 .flexbox .container { display: flex; } 控制样式es6-promise 或 fetch,那得靠 loadjs 或 polyfill.io
服务端通过 User-Agent 字符串识别浏览器版本,对 HTML5 兼容性参考价值极低。例如:
WebKit/534.30,看似新,但不支持 Promise 和 classList
Chrome/67,实际 JS 引擎是旧版 JSCore,Array.from 直接报错MSIE 10.0 支持 canvas,但 canvas.toBlob() 要到 Edge 14 才有如果必须服务端区分,只用于简单资源降级(如给 IE9 返回 video.mp4 而非 video.webm),别用来决定是否加载 ES6 模块。
上线后用 window.onerror + performance.getEntriesByType('navigation') 记录失败率,比开发时模拟更有说服力:
if ('sendBeacon' in navigator) {
window.addEventListener('error', (e) => {
navigator.sendBeacon('/log', JSON.stringify({
url: location.href,
error: e.error?.toString() || e.message,
ua: navigator.userAgent
}));
});
}
你会发现:某些“理论上兼容 HTML5”的设备(如国产低端平板的定制 Android 6 系统),fetch 会静默失败,Intl.DateTimeFormat 报 RangeError,这些根本不在任何检测清单里。