在 nginx 中实现移动端自适应重定向,核心做法是在 `server` 块内使用 `if` 指令匹配请求头中的 `user-agent`,识别出移动设备后,通过 `return 302` 将请求跳转到指定的 m 域名。具体操作是定义一个包含常见移动端标识的正则表达式,当请求命中该规则时,立即终止当前处理并返回 302 状态码及新 url,浏览器收到后会发起对新域名的请求,从而实现页面跳转。

如何准确识别移动端 User-Agent
要准确识别移动端,需要构建一个覆盖主流移动设备的正则表达式,并配合 Nginx 的变量捕获功能。Nginx 本身没有内置的移动检测模块,因此必须依赖 `~*` 进行不区分大小写的正则匹配。匹配成功后,可以将原始 URI 存入变量,以便在重定向时保留路径和参数,确保用户从首页进入也能正确跳转到移动版对应页面。

server {
listen 80;
server_name www.example.com;
# 定义移动端 UA 的正则表达式
set $mobile_rewrite do_not_perform;
if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino") {
set $mobile_rewrite perform;
}
if ($mobile_rewrite = perform) {
# 捕获原始 URI,包括查询字符串
return 302 http://m.example.com$request_uri;
}
location / {
root /var/www/html;
index index.html;
}
}
上述配置中,`$http_user_agent` 变量存储了客户端发送的 User-Agent 字符串。正则表达式涵盖了 Android、BlackBerry、iPhone、Windows Phone 等主流平台的关键标识。一旦匹配成功,`$mobile_rewrite` 被设为 `perform`。随后的 `if` 判断确认该变量值后,执行 `return 302`。`$request_uri` 自动包含了路径和查询参数,例如访问 `www.example.com/page?id=1` 会被重定向到 `m.example.com/page?id=1`。这种写法避免了手动拼接 URL 的错误风险。
如何处理非移动设备与缓存冲突
对于非移动设备,Nginx 应正常提供桌面版内容,且需确保重定向逻辑不会干扰静态资源或 API 请求。同时,为了避免移动端用户频繁切换导致缓存混乱,应在重定向响应中设置合适的 Cache-Control 头,或者在 m 域名上独立管理缓存策略。此外,若希望允许用户手动切换回桌面版,需在 m 域名侧提供反向跳转机制,但本方案仅聚焦于从主域到 m 域的单向自适应。

server {
listen 80;
server_name www.example.com;
# 排除特定路径,如 API 或静态资源,避免误重定向
location /api/ {
proxy_pass http://backend_api;
}
location /static/ {
alias /var/www/static/;
expires 30d;
}
# 移动端重定向逻辑
set $mobile_rewrite do_not_perform;
if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino") {
set $mobile_rewrite perform;
}
if ($mobile_rewrite = perform) {
# 添加 Cache-Control 防止移动端缓存桌面版内容
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
return 302 http://m.example.com$request_uri;
}
location / {
root /var/www/html;
index index.html;
}
}
在实际部署中,API 接口和静态资源通常不需要重定向到移动端域名,因为它们可能被桌面端应用或第三方服务调用。通过在 `location` 块中明确指定 `/api/` 和 `/static/` 的处理方式,可以绕过后续的 `if` 重定向逻辑(注意:Nginx 中 `if` 在 `location` 外生效,但若在 `location` 内使用需谨慎,此处假设重定向逻辑位于 `server` 级别或优先匹配的 `location`)。更稳妥的做法是将重定向逻辑放在独立的 `location` 或使用 `map` 指令优化性能。`add_header` 确保了重定向响应不被缓存,强制浏览器每次检查 UA。若用户通过书签直接访问 m 域名,则无需此逻辑,m 域名服务器应独立配置为默认提供移动版内容。
基于 User-Agent 匹配失败时的降级处理
当某些新型移动设备或自定义 UA 未能命中预设的正则表达式时,重定向将失效,用户仍停留在主域名。为解决此问题,可引入基于屏幕分辨率的 JavaScript 辅助检测,或在 Nginx 中增加对 `$http_x_wap_profile` 等 WAP 特有头的检查。另一种策略是启用“移动优先”索引,即默认所有请求都视为移动端,仅在检测到明确的桌面 UA 时才提供桌面版,但这可能影响 SEO 和用户体验,需权衡使用。在本配置中,若匹配失败,请求将落入默认的 `location /` 块,继续提供桌面版内容,这是安全的降级行为。











