通过正则匹配user-agent中mobile、android、ios、sec-ch-ua-mobile等关键词判断,辅以自定义header;需区分缓存key、日志标记及错误码字段以避免移动端与桌面端逻辑混淆。

怎么判断请求来自移动端还是桌面端
Fiber 本身不提供 UA 自动分类中间件,c.Get("User-Agent") 是唯一可靠入口。别信 c.IsMobile() 这类不存在的函数——Fiber v2/v3 都没内置这个方法。
实际判断靠正则匹配常见关键词:Mobile、Android、iOS、、<code>iPad,但要注意 iPad 在某些新版 Safari UA 里不带 Mobile,得单独列;Windows Phone 已淘汰,可忽略。
- 推荐用轻量正则:
/(?i)mobile|android|iphone|ipad|ios/ - 别用第三方 UA 解析库(如 uap-go)——增加依赖、启动慢、多数场景纯属过度设计
- 注意:微信内置浏览器 UA 含
MicroMessenger,但不必然代表移动设备;得结合Mobile或屏幕特征头(如Sec-CH-UA-Mobile)交叉验证
如何在同一个路由里返回不同结构的 JSON
不是靠写两个路由,而是根据 UA 动态构造响应体。关键点:字段裁剪比格式转换更常用,比如移动端不要 created_at 微秒级时间戳、不要冗余关联数据。
示例场景:用户详情接口 GET /users/:id,移动端只返回 name、avatar、bio,桌面端额外加 joined_at、last_login_ip、settings。
- 定义两个 struct:
type UserMobileResp struct { Name, Avatar, Bio string }和UserDesktopResp,字段按需拆分 - 别用 map[string]interface{} 拼接——类型不安全、IDE 无提示、JSON 序列化性能略差
- 避免在 handler 里做大量 if-else 字段赋值;优先用 struct 转换函数封装逻辑
为什么 c.Accepts("json") 不能替代 UA 判断
c.Accepts("json") 只检查请求头 Accept: application/json,和终端类型完全无关。浏览器、curl、Postman 默认都发这个头,它解决的是“要什么格式”,不是“从哪来”。
真实项目中常遇到:后台管理页用桌面浏览器访问,但调用同一 API;小程序后端也走这个接口,UA 却是 miniprogram。这时候仅靠 Accept 会误判。
-
Accept头适合做内容协商(比如同时支持 JSON/XML),不适合终端适配 - 如果真要多格式+多终端组合,优先级应为:
User-Agent>Sec-CH-UA-Mobile(Chromium 新标准) > 自定义 header(如X-Client-Type: mobile) - 别把
Accept当兜底——它根本兜不住终端差异
移动端字段精简时最容易漏掉的坑
表面看只是少几个字段,但实际影响链路比想象中长:数据库查询、缓存 key、日志打点、错误码语义都可能被牵连。
- 数据库层:别为了省字段就临时改 SQL
SELECT *→SELECT name, avatar;统一用预编译查询 + struct scan,移动端用子集 struct 接收即可 - Redis 缓存:移动端和桌面端若共用一个 key(如
user:123),会导致缓存污染;建议加前缀:user:123:mobile/user:123:desktop - 日志里别只记
"user fetched",要体现终端类型:log.Printf("user %d fetched by %s", id, clientType) - 最隐蔽的坑:移动端返回 400 错误时,错误消息字段名(如
field_errors)是否和桌面端一致?前后端契约必须对齐,否则前端解析崩溃











