本文约 3,259 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:证书是绿的,百度搜出来还是 http
不少站长遇到过这种尴尬:Let’s Encrypt 证书装好了,浏览器地址栏是绿锁,nginx 也做了 301,但在百度搜索里点开自己的页面,URL 依然是 http:// 开头,甚至出现「http 版本已收录、https 版本未收录」的并存状态。再过几周,收录量不升反降。根源通常有两个:一是站点在百度搜索资源平台里是按 http:// 协议验证的,HTTPS 版本没有单独完成认证;二是页面里还混着 http 资源(图片、JS、CSS),百度判定该页不是「完全 HTTPS 页面」,认证过不了。把这两件事理顺,HTTPS 迁移才算真正完成。
原理分析:百度眼中的「完全 HTTPS 页面」
百度搜索资源平台的 HTTPS 认证,位于「站点管理 → 站点属性」中,提交后百度会校验:站点所有页面是否都能通过 https 正常访问、http 是否 301 跳转到 https、证书是否有效且未过期、页面内是否还有 http 子资源。认证通过后,百度在索引替换时会优先保留 https 版本,并且对 HTTPS 页面给予一定的排序优待。注意,百度是把 http:// 与 https:// 当作两个不同站点来对待的,两者需要分别添加验证。这与 Google Search Console 的属性体系是同一套逻辑。
| 检查项 | 不合格表现 | 排查方式 |
|---|---|---|
| 全站可 https 访问 | 个别页面仍可 http 打开 | 批量 curl 状态码 |
| http 301 到 https | 返回 302 或 200 | curl -I 看 Location |
| 证书有效 | 过期、域名不匹配、链不完整 | 浏览器/SSL Labs |
| 无混合内容 | 图片/脚本仍是 http | 源码搜索 src="http:// |
| sitemap 用 https | sitemap 里全是 http | 打开 sitemap 检查 |
保姆级实操
步骤 1:先做全量备份,再装证书。 证书可以用 certbot 签 Let’s Encrypt,也可以用在云厂商申请的免费 DV 证书。装完后先在测试路径验证证书链完整(中间证书缺失是移动端报证书警告的常见原因)。
步骤 2:在 nginx 层做统一 301。 注意要把 http 与 https 两个 server 块分开写,跳转只发生在 http 块内,避免 https 块内部循环跳转:
server {
listen 80;
server_name mimangfei.com www.mimangfei.com;
return 301 https://mimangfei.com$request_uri;
}
server {
listen 443 ssl http2;
server_name mimangfei.com;
ssl_certificate /etc/letsencrypt/live/mimangfei.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mimangfei.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# 只在 HTTPS 下发送 HSTS,先设较短的 max-age 观察
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
try_files $uri $uri/ /index.php?$args;
}
}
步骤 3:改 WordPress 的两个地址。 后台「设置 → 常规」里的 WordPress 地址与站点地址都要换成 https,改完顺手在「设置 → 固定链接」点一次保存,刷新重写规则。
步骤 4:清理数据库里的历史 http 链接。 正文里的图片地址不会因为你改了站点地址就自动变。先用 SQL 摸清规模:
-- 统计正文里残留 http 资源的文章数
SELECT COUNT(*) AS dirty_posts
FROM wp_posts
WHERE post_status = 'publish'
AND post_content LIKE '%src="http://%';
-- 抽样看具体是哪些文章
SELECT ID, post_title
FROM wp_posts
WHERE post_status = 'publish'
AND post_content LIKE '%src="http://%'
LIMIT 50;
确认后批量替换(post_content 不是序列化数据,可以直接 REPLACE):
UPDATE wp_posts
SET post_content = REPLACE( post_content, 'src="http://mimangfei.com', 'src="https://mimangfei.com' )
WHERE post_status = 'publish'
AND post_content LIKE '%src="http://mimangfei.com%';
注意 wp_options、wp_postmeta 里可能存在序列化数据,那里不要用裸 SQL 替换,应该交给 WP-CLI 的 wp search-replace 处理,否则长度字段对不上,小工具会整片消失。
步骤 5:提交 HTTPS 认证与改版规则。 在资源平台添加 https:// 站点并完成验证,然后在「网站改版」里提交 HTTP→HTTPS 的规则改版。同时把 sitemap 全量替换成 https 版本重新提交,并对确定不再使用的 http URL 走死链提交。
步骤 6:观察 4–6 周。 HTTPS 迁移后索引替换需要时间,期间 http 与 https 并存是正常现象,不要因为短期收录下降就撤销跳转。
常见踩坑
- 跳转写成 302,百度不会认为这是永久迁移,索引替换迟迟不启动。
- 案例: 某站加了 HSTS 且
max-age设成一年,结果 CDN 节点证书配置遗漏,部分用户被浏览器硬跳到 https 后直接证书报错,且因 HSTS 无法回退,只能紧急补证书。 - 只对首页加了跳转,
/wp-content/uploads/下的图片仍可用 http 直接访问。 - 忘了改 sitemap,Yoast 或 Rank Math 生成的 sitemap 里仍是 http,等于自己告诉百度旧地址才是主要的。
- 混合内容只清了
src,没清 CSS 里的url(http://...)背景图。 - 证书只签了裸域,没包含 www,用户从带 www 的旧外链进来就报证书告警。
- 迁移期内又顺便改了 URL 结构,两个变量叠加,事后无法判断是哪个导致的掉量。
总结
HTTPS 迁移是否成功,看三个标志:资源平台里 https 站点的认证状态变为已认证、抓取诊断返回的是 https 页面且无混合资源告警、索引量在四到六周内回到迁移前水平并有增量。行动清单:备份 → 装证书验链 → nginx 301 → 改站点地址并刷新固定链接 → SQL 清理正文 http → WP-CLI 处理序列化字段 → 提交 HTTPS 认证与改版规则 → 换 sitemap。域名层面的主域统一问题见 www 与非 www 域名统一,抓取层面的细节可延伸阅读 百度抓取诊断工具使用。
