惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派
2025年 Safari 和 iOS版本检测新思路 - 少数派
2025-12-10 · via 少数派

大家好,我是 Immerse,一名独立开发者、内容创作者、AGI 实践者。

关注公众号:沉浸式趣谈,获取最新文章(更多内容只在公众号更新)

个人网站:https://yaolifeng.com 也同步更新。

转载请在文章开头注明出处和版权信息。

我会在这里分享关于编程独立开发AI干货开源个人思考等内容。

如果本文对您有所帮助,欢迎动动小手指一键三连(点赞评论转发),给我一些支持和鼓励,谢谢!


最近看到一篇文章,针对于 Safari 和 iOS 版本检测很不错,分享出来给大家。

之前都用 User-Agent 一把嗦,但文章提到检测结果不准确。

两个方式

  1. User-Agent
  2. 特性检测

User-Agent 检测

这个方法就是获取浏览器的 User-Agent,从里面提取版本信息。

但是有问题,这个结果不准确。

Safari 的 UA 字符串里有两个版本号,一个是技术版本,一个是市场版本。很多脚本会把这俩搞混。

还有一点,从 macOS 11 开始,Safari 的 UA 里系统版本就不更新了,永远显示 10.15.7。

所以想从 UA 里准确获取版本?基本不可能。

MDN 官方都说了,别依赖 UA 字符串做浏览器检测逻辑,这是个常见 bug 源头。

特性检测

苹果官方推荐: 特性检测。

就是直接检查浏览器支不支持某个 API 或 CSS 特性。

但它没法区分所有版本,因为很多特性在好几个版本里都有。

解决思路

把两种方法结合起来用, 主要靠特性检测,UA 检测作为补充。

第一步:检测 WebKit 引擎

在 iOS 上,所有浏览器都必须用 WebKit,包括 Chrome、Firefox 这些。

所以检测 WebKit 能帮我们缩小范围:

// 桌面 Safari 和所有 iOS 浏览器
function isWebkit() {
    return 'GestureEvent' in window;
}

// 所有移动端 WebKit 浏览器
function isMobileWebKit() {
    return 'ongesturechange' in window;
}

// 只检测桌面 Safari
function isDesktopWebKit() {
    return typeof window !== 'undefined' && 'safari' in window && 'pushNotification' in window.safari;
}

第二步:检测特定 iOS 版本

去查 Safari 发布说明或 WebKit 的更新日志,找到某个版本新增的特性。

比如我想检测 iOS 17.0,发现这个版本加入了 contain-intrinsic-size 支持。

那就检测这个特性:

// iOS 17.0+ 返回 true
const isAtLeastiOS17 = CSS.supports('contain-intrinsic-size', '100px');

如果要检测具体的小版本,可以配合下一个版本的特性来排除。

比如 ManagedMediaSource 是在 iOS 17.1 才有的:

const supportsManagedMediaSource = 'ManagedMediaSource' in window;

// 只匹配 iOS 17.0
function isOnlyiOS170() {
    return isAtLeastiOS17 && !supportsManagedMediaSource;
}

if (isMobileWebKit()) {
    if (isOnlyiOS170()) {
        // 这是 iOS 17.0
    }
}

第三步:真机测试

理论归理论,实际测试才是王道。

踩坑:

iOS 17.6 的发布说明里说支持 CSS 的 safe 关键字,用 @supports 检测也返回 true。

结果真机上一跑,根本不生效。

这种情况下,只能换个思路,检测实际的渲染效果:

const isSafeKeywordSupported = () => {
    const container = document.createElement('div');
    const child = document.createElement('span');

    child.textContent = 'Evil Martians';

    container.style.display = 'flex';
    container.style.justifyContent = 'safe center';
    container.style.width = '5%';
    container.style.position = 'absolute';
    container.style.top = '-9999px';
    container.style.left = '-9999px';

    container.appendChild(child);
    document.body.appendChild(container);

    const containerRect = container.getBoundingClientRect();
    const childRect = child.getBoundingClientRect();
    const isCroppedOnLeft = childRect.left < containerRect.left;

    document.body.removeChild(container);
    return !isCroppedOnLeft;
};

通过检查元素的实际渲染位置,判断特性是不是真的生效了。

第四步:配合 UA 检测

有时候特性检测也不够用。

比如要区分 iPad 和其他设备。

iPad 的 UA 字符串跟 macOS 上的 Safari 一模一样。

但如果 UA 显示是 macOS,特性检测又显示是移动端 WebKit,那就能判断出这是 iPad:

// 检测 iPadOS
function isiPad() {
    return isDesktopWebKit() && isMobileWebKit();
}

几个关键点

WebKit 不等于 Safari,iOS 上所有浏览器都用 WebKit。

主要用特性检测,UA 检测只是补充。

多看 Safari 和 WebKit 的发布说明,但也别全信,因为有些变更根本没写进去。

真机测试不能省,有些 bug 只有在实际设备上才能发现。

有时候 @supports 会撒谎,浏览器说支持但实际不行,这时候得检查实际渲染效果。

写在最后

核心思路就是:特性检测为主,UA 检测为辅,真机测试验证。

参考资料

  • https://developer.apple.com/documentation/safari-release-notes
  • https://webkit.org/
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Browser_detection_using_the_user_agent