一个链接,两种命运

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

需求很明确:

  • 前台贴一张二维码,教练和会员都扫它;
  • 教练用 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 做快筛,尺寸和触摸做兜底,服务端做管控,一个链接也能走出两条路。

相关推荐
VOLUN11 分钟前
PageLayout布局组件封装技巧
前端·javascript·vue.js
掘金安东尼11 分钟前
React 的 use() API 或将取代 useContext
前端·javascript·react.js
牛马喜喜12 分钟前
记录一次el-table+sortablejs的拖拽bug
前端
一枚前端小能手16 分钟前
⚡ Vite开发体验还能更爽?这些配置你试过吗
前端·vite
anyup32 分钟前
🔥 🔥 为什么我建议你使用 uView Pro 来开发 uni-app 项目?
前端·vue.js·uni-app
Skelanimals33 分钟前
Elpis全栈框架开发总结
前端
蓝胖子的小叮当37 分钟前
JavaScript基础(十三)函数柯里化curry
前端·javascript
孪创启航营40 分钟前
数字孪生二维热力图制作,看这篇文章就够了!
前端·three.js·cesium
宫水三叶的刷题日记43 分钟前
真的会玩,钉钉前脚辟谣高管凌晨巡查工位,小编随后深夜发文
前端·后端·面试
zzywxc7871 小时前
AI 行业应用:金融、医疗、教育、制造业领域的落地案例与技术实现
android·前端·人工智能·chrome·金融·rxjava