From 18537c5dba51f98bb28fdaa0db58e099e9ca14c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Tue, 15 Sep 2026 15:58:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(sdk):=20=E8=AE=BE=E5=A4=87=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E9=A1=BA=E5=BA=8F=E4=BF=AE=E8=AE=A2=EF=BC=88iPad/Fire?= =?UTF-8?q?fox=20=E5=B9=B3=E6=9D=BF=E5=85=88=E5=88=A4=EF=BC=89+=20FxiOS=20?= =?UTF-8?q?=E5=89=8D=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - device_type:iPad/Tablet 先于 Mobile/Android/iPhone 判(真实 iPad UA 恒含 Mobile 串、Firefox Android 平板显式 '; Tablet;',旧顺序误判手机) - browser:Firefox/FxiOS 前移至 Safari 之前(iOS Firefox UA 尾部恒含 Safari/,旧顺序为死代码) - 测试 23 过(翻转 iPad 锁定测试 + 新增 Android 平板、iOS Firefox 两条) Co-Authored-By: Claude Code --- sdk/src/context.ts | 11 +++++++---- sdk/test/context.test.ts | 28 +++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/sdk/src/context.ts b/sdk/src/context.ts index 210c7d9..9bda146 100644 --- a/sdk/src/context.ts +++ b/sdk/src/context.ts @@ -53,8 +53,10 @@ export function parseUtm(search: string): Record { } function detectDeviceType(ua: string): string { - if (/Mobile|Android|iPhone/.test(ua)) return "手机"; + // iPad/Tablet 先判(规格修订):真实 iPad UA 恒含 Mobile 串、Firefox Android 平板 + // 显式 "; Tablet;"——若先判 Mobile/Android 会把它们误归为"手机" if (/iPad|Tablet/.test(ua)) return "平板"; + if (/Mobile|Android|iPhone/.test(ua)) return "手机"; return "PC"; } @@ -68,13 +70,14 @@ function detectOs(ua: string): string { } function detectBrowser(ua: string): string { - // MicroMessenger 必须最先测:微信 WebView 的 UA 内嵌 Chrome/Safari 引擎串, - // 与 "Edg 必须先于 Chrome" 同理(后测永远轮不到)。 + // MicroMessenger 最先测:微信 WebView 的 UA 内嵌 Chrome/Safari 引擎串; + // FxiOS(iOS Firefox)先于 Safari 测:其 UA 尾部恒含 Safari/——与 "Edg 必须先于 + // Chrome" 同一死代码模式,后测永远轮不到。 if (/MicroMessenger/.test(ua)) return "WeChat"; if (/Edg(e|A|iOS)?\//.test(ua)) return "Edge"; if (/Chrome\/|CriOS\//.test(ua)) return "Chrome"; - if (/Safari\//.test(ua)) return "Safari"; if (/Firefox\/|FxiOS\//.test(ua)) return "Firefox"; + if (/Safari\//.test(ua)) return "Safari"; return ""; } diff --git a/sdk/test/context.test.ts b/sdk/test/context.test.ts index 334f631..bd6843d 100644 --- a/sdk/test/context.test.ts +++ b/sdk/test/context.test.ts @@ -13,10 +13,15 @@ const UA_IPHONE_SAFARI = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (Version/17.0 Mobile/15E148 Safari/604.1"; const UA_TABLET = "Mozilla/5.0 (X11; Tablet; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"; -// 真实 iPad Safari UA 恒含 Mobile 串——按任务规格的判定顺序(Mobile 先于 iPad) -// 会落入"手机",此处锁定该规格行为,避免后人无意"修复" +// 真实 iPad Safari UA 恒含 Mobile 串——规格修订:iPad/Tablet 先判,归"平板" const UA_IPAD_REAL = "Mozilla/5.0 (iPad; CPU OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (Version/16.0 Mobile/15E148 Safari/604.1"; +// Firefox Android 平板 UA:显式 "; Tablet;" 且含 Android 无 Mobile——旧顺序会误判手机 +const UA_ANDROID_TABLET_FF = + "Mozilla/5.0 (Android 13; Tablet; rv:121.0) Gecko/121.0 Firefox/121.0"; +// iOS Firefox UA:FxiOS + 尾部恒含 Safari/604.1——Firefox 检测须先于 Safari +const UA_IOS_FIREFOX = + "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/121.0 Mobile/15E148 Safari/604.1"; const UA_WIN_CHROME = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"; const UA_WIN_EDGE = @@ -96,9 +101,26 @@ describe("buildEnvContext", () => { expect(buildEnvContext().device_type).toBe("平板"); }); - it("真实 iPad UA(含 Mobile 串)→ 手机:规格判定顺序 Mobile 先于 iPad", () => { + it("真实 iPad UA(含 Mobile 串)→ 平板:规格修订 iPad/Tablet 先于 Mobile 判", () => { stubUA(UA_IPAD_REAL); const env = buildEnvContext(); + expect(env.device_type).toBe("平板"); + expect(env.os).toBe("iOS"); + expect(env.browser).toBe("Safari"); + }); + + it("Firefox Android 平板 UA(Android + '; Tablet;')→ 平板", () => { + stubUA(UA_ANDROID_TABLET_FF); + const env = buildEnvContext(); + expect(env.device_type).toBe("平板"); + expect(env.os).toBe("Android"); + expect(env.browser).toBe("Firefox"); + }); + + it("iOS Firefox UA(FxiOS + Safari 串)→ Firefox:FxiOS 先于 Safari 判", () => { + stubUA(UA_IOS_FIREFOX); + const env = buildEnvContext(); + expect(env.browser).toBe("Firefox"); expect(env.device_type).toBe("手机"); expect(env.os).toBe("iOS"); });