本文约 3,633 字,预计阅读 10 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:三种适配方案,选错要多维护三年
站点要做移动端时,摆在面前的是三条路:给移动用户单独做一套 m 站(跳转适配)、一套 HTML 适配所有屏幕(自适应)、同一 URL 按 UA 输出不同 HTML(代码适配)。三条路都能跑通,但维护成本差了一个数量级。见过太多站点因为早期选了跳转适配,后期每加一个功能都要改两遍、每次改版都要重做适配关系,最后被迫推倒重来。本文把三种方案摆在一起对比,并给出各自的正确配置方式。
原理分析:三种方案的本质区别
- 跳转适配:PC 与移动是两套 URL(如
www与m.),服务器根据 UA 返回 301/302 跳转,并通过rel="alternate"与rel="canonical"双向声明对应关系。百度需要额外维护”适配关系”。 - 自适应(响应式):同一 URL、同一份 HTML,靠 CSS 媒体查询适配不同屏幕。百度抓一次即可,无需适配关系,出错概率最低。
- 代码适配:同一 URL,但服务器根据 UA 返回不同的 HTML 结构。必须输出
Vary: User-Agent响应头,否则缓存会串味(移动用户拿到 PC 缓存)。
对比:
| 维度 | 跳转适配 | 自适应 | 代码适配 |
|---|---|---|---|
| URL 结构 | 两套 | 一套 | 一套 |
| 适配关系声明 | 必需 | 不需要 | 不需要 |
| 维护成本 | 最高(改两遍) | 最低 | 中(模板分支) |
| 缓存风险 | 低 | 低 | 高(须 Vary) |
| 百度推荐度 | 一般 | 推荐 | 一般 |
| 出错表现 | 移动页跳首页 | 布局错乱 | 内容串版 |
结论对新站很明确:优先自适应。只有在 PC 与移动端功能结构差异极大、无法用 CSS 收敛时,才考虑另两种。
保姆级实操
方案一:自适应(推荐)
只需保证主题响应式与 viewport 正确,无需服务器配置。核心是 CSS:
<!-- 唯一必需:viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 响应式布局示例:窄屏单列,宽屏两列 -->
<style>
.container { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 768px) {
.container { grid-template-columns: 1fr 300px; }
}
</style>
方案二:跳转适配(双版本站点)
Nginx 按 UA 跳转,注意必须跳转到”对应页面”而不是首页:
# 用 map 判断移动端 UA
map $http_user_agent $is_mobile {
default 0;
"~*(android|iphone|ipod|windows phone|blackberry|mobile)" 1;
}
server {
listen 443 ssl http2;
server_name www.mimangfei.com;
# PC 页:移动 UA 访问时 302 到对应的移动页(保留路径)
if ( $is_mobile ) {
return 302 https://m.mimangfei.com$request_uri;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
}
server {
listen 443 ssl http2;
server_name m.mimangfei.com;
# 移动页:PC UA 访问时跳回 PC 对应页
if ( $http_user_agent !~* "(android|iphone|ipod|windows phone|blackberry|mobile)" ) {
return 302 https://www.mimangfei.com$request_uri;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
}
跳转后,HTML 里必须补双向声明:
<!-- PC 页 head -->
<link rel="alternate" media="only screen and (max-width: 640px)"
href="https://m.mimangfei.com/some-post/">
<!-- 移动页 head -->
<link rel="canonical" href="https://www.mimangfei.com/some-post/">
方案三:代码适配
同一 URL 输出不同 HTML,必须带 Vary 头:
# 让缓存系统按 UA 分别缓存
add_header Vary "User-Agent" always;
# 若使用 Nginx 缓存,需把 UA 加入缓存键
proxy_cache_key "$scheme$request_method$host$request_uri$http_user_agent";
<?php
// WordPress 侧:按 UA 切换模板分支(示例,仅演示结构判断)
add_filter( 'template_include', function ( $template ) {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$mob = preg_match( '/android|iphone|ipod|windows phone|mobile/i', $ua );
$file = $mob ? 'single-mobile.php' : 'single.php';
if ( locate_template( array( $file ) ) ) {
return locate_template( array( $file ) );
}
return $template;
} );
验证三步
curl -I确认跳转保留路径(url_effective是对应页而非首页);- 移动 UA 与 PC UA 各抓一次,比对正文是否一致;
- 代码适配必须确认响应头含
Vary: User-Agent。
常见踩坑
- 跳转一律跳首页:最致命的错误,等于整站适配关系失效。
- 代码适配没加 Vary:CDN 缓存 PC 版给移动用户,表现为”手机上看到 PC 布局”。
- 用 JS 做跳转:百度抓取时不执行 JS,无法感知适配关系。
- 双版本 URL 路径不一致:
/post-name/与/m/2026/10/post-name.html无法一一对应,适配关系建立失败。 - 案例:某站代码适配上线后,移动端用户频繁看到 PC 版布局。排查发现 CDN 缓存键里没有 UA,且源站没输出 Vary 头,CDN 把 PC 版本缓存给了所有人。补上
Vary: User-Agent并把 UA 加入缓存键后问题解决。 - 自适应站点又额外做了 m 站:两套并存会造成重复内容,canonical 处理不当还会互相打架;同理,也不建议再叠加MIP现状与是否还需要接入这类独立版本页面。
- 跳转用 301 导致 PC 无法访问:双版本互跳时应使用 302(临时),301 会让浏览器与爬虫缓存跳转结果。
总结
判断标准:新站一律自适应;已有 m 站且运转正常可维持跳转适配,但要确保一一对应并使用 302;代码适配只在有强工程能力、能正确处理 Vary 与缓存键时才用。行动清单:评估功能差异是否大到需要两套模板 → 默认走自适应 → 双版本配置 Nginx UA 跳转(302、保留路径)→ 补 alternate/canonical 双向声明 → 代码适配补 Vary 与缓存键 → 用移动 UA 与 PC UA 双向验证。移动端内容与体验的通用要点见百度移动搜索收录与适配要点。
