一个链接,两种命运

你在给某连锁健身房做「会员扫码签到」系统。

需求很明确:

  • 前台贴一张二维码,教练和会员都扫它;
  • 教练用 PC 后台管理,要打开 Web 管理系统(React);
  • 会员用手机扫码,要跳转 H5 轻应用(Vue);

结果第一版上线,会员扫完直接进了后台首页,一脸懵:"这表格是干啥的?"

你立刻意识到:同一个链接,必须智能分流


解决方案:三层识别 + 渐进式加载

1. 表面用法:用 User-Agent 做第一道筛子

js 复制代码
// router.js
const PC_UA = /Windows|Macintosh|Linux/;
const MOBILE_UA = /Android|iPhone|iPad|iPod/;

function getDeviceType() {
  const ua = navigator.userAgent;
  if (PC_UA.test(ua)) return 'pc';
  if (MOBILE_UA.test(ua)) return 'mobile';
  // 🔍 降级:看屏幕宽度
  return window.innerWidth < 768 ? 'mobile' : 'pc';
}
js 复制代码
// entry.js
async function main() {
  const type = getDeviceType();
  if (type === 'pc') {
    await import('./web-app.js');      // 🔍 动态加载 PC 版
  } else {
    location.href = 'https://m.corp.com/app'; // 🔍 跳 H5
  }
}
main();

关键点:

  • PC 端直接加载 SPA,不跳转,体验无缝;
  • 手机端跳转到独立 H5 域名,便于独立迭代和 SEO。

2. 底层机制:为什么不能只靠 UA?

识别方式 准确率 风险 适用场景
User-Agent 90% 可伪造,部分平板 UA 模糊 快速分流
屏幕尺寸 85% 折叠屏、横屏 iPad 易误判 降级兜底
触摸支持 95% maxTouchPoints > 1 更准 辅助判断

最终用 组合判断 提升准确率:

js 复制代码
function isMobile() {
  const ua = navigator.userAgent;
  if (/Android|iPhone/.test(ua)) return true;
  if (/iPad|Macintosh/.test(ua) && 'ontouchend' in document) return true; // 🔍 iPadOS
  return window.innerWidth <= 768 && navigator.maxTouchPoints > 1;
}

3. 设计哲学:把"分流"做成中间层服务

与其在每个项目里重复写判断逻辑,不如抽成一个 轻量级网关层

js 复制代码
// gateway.js (Node.js)
app.get('/entry', (req, res) => {
  const { userAgent, 'x-forwarded-for': ip } = req.headers;
  const isMobile = /Android|iPhone|Mobile/.test(userAgent);
  
  if (isMobile) {
    res.redirect('https://m.corp.com/app?from=' + ip); // 🔍 带来源信息
  } else {
    res.sendFile(path.join(__dirname, 'web/index.html')); // 🔍 直接吐 PC 页面
  }
});

这样前端只维护一个入口页,逻辑全在服务端,便于灰度、埋点、拦截爬虫


应用扩展:可复用的配置片段

1. 静态页分流模板(零后端依赖)

html 复制代码
<!-- index.html -->
<script>
  (function() {
    const mobileRegex = /Android|iPhone|iPad|iPod|Mobile/;
    if (mobileRegex.test(navigator.userAgent)) {
      location.replace('https://m.corp.com/app');
    }
    // 否则继续加载 React/Vue 脚本
  })();
</script>

2. 环境适配说明

场景 注意点
微信内置浏览器 UA 含 MicroMessenger,但仍是 mobile,正常跳 H5
iPadOS 默认 UA 像 Mac,需检测 ontouchendmaxTouchPoints
PWA 安装后 window.matchMedia('(display-mode: standalone)') 可识别,但分流不依赖它

举一反三:3 个变体场景

  1. App 内嵌 H5 智能跳转
    在 UA 里加自定义字段 MyApp/1.0,识别到后跳 myapp://page/signin 唤起原生页。
  2. PC 平板混合设备(Surface)
    先按 PC 加载,但监听页面 touchstart 事件,3 秒内有触摸则提示:"检测到触屏,是否切换平板模式?"
  3. AB 测试分流
    在 gateway 层加逻辑:Math.random() < 0.1 的 mobile 用户强制看 PC 版,收集体验反馈。

小结

别让设备类型决定代码,而要让代码聪明地认识设备。

用 UA 做快筛,尺寸和触摸做兜底,服务端做管控,一个链接也能走出两条路。

相关推荐
程序员黑豆4 小时前
Java包装类:基本类型与对象的桥梁
java·前端·ai编程
bugcome_com7 小时前
JWT 知识小课堂:从入门到精通,一文吃透 JSON Web Token
前端·json
To_OC7 小时前
写了三天 Next.js,我的 React 世界观被拆了又装回去
前端·全栈·next.js
独泪了无痕7 小时前
viewer.js 安装与配置指南:实现图片预览功能
前端·vue.js
Fluxart.ai9 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
why技术10 小时前
AI 写的文章,可能都带着手敲一遍都去不掉的“隐形水印”。
前端·人工智能·后端
愚公搬代码10 小时前
【愚公系列】《Android应用案例开发大全》016-LBS类应用掌上杭州(辅助工具类的开发)
android·前端
CodeSheep10 小时前
又一个华为天才少年,离职了!
前端·后端·程序员
kyriewen10 小时前
面试官说"打开你的AI工具"——我才发现,他考的根本不是写代码
前端·人工智能·面试
IT_陈寒11 小时前
Vue的双向绑定把我坑惨了,原来这个场景不能用
前端·人工智能·后端