本文约 2,741 字,预计阅读 7 分钟。文中命令与配置均经过实测,可直接参考执行。
引言
站点搬到新域名后,文章文字都在,排版也正常,可配图全变成一个个裂开的图标,右键「复制图片地址」一看,src 里写的还是 http://旧域名.com/wp-content/uploads/...。同样的问题还会出现在文章内的站内链接、缩略图、甚至一些页脚信息上——只要当初写进数据库的是绝对地址,换域名后它们就全部指向已经废弃的旧站。
这不是图片文件没传上来,而是数据库里存的是「旧域名+路径」的绝对 URL。文件其实好端端躺在 wp-content/uploads 里,只是网页去找旧域名要图,旧域名当然给不出来。解决办法就是把这些旧域名批量替换成新域名。注意:绝对不能只用文本编辑器全局替换,因为 WordPress 的一些配置是序列化(serialized)存储的,粗暴替换会破坏数据结构。下面给出三种安全做法。
故障原因分析
- 数据库里存的是绝对 URL。 WordPress 插入图片时,把完整域名一起写进了
wp_posts的post_content字段,换域名后这些地址自然失效。
wp_options里的home和siteurl未更新。 只要这两项还是旧域名,主题生成的图片、样式、脚本地址都会指向旧站。
- 序列化数据不能直接文本替换。 主题选项、小工具设置等以
s:长度:"字符串"形式存储,替换后字符串变长但长度没改,反序列化会失败,导致配置丢失。
- CDN 或缓存插件记录了旧地址。 部分插件、CDN 会把域名写进缓存或配置,换域名后仍输出旧链接。
- 上传目录结构或权限变化。 少数情况下图片确实没迁移完整,或
uploads目录权限不足,需与「链接指向旧域名」区分排查。
分步解决方案
判断原则:右键查看图片链接,如果地址里是旧域名,就是本文要解决的问题;如果是新域名但图仍裂,那要查文件是否真的上传了。
方法一:登录后台用插件安全替换(推荐新手)
用「Better Search Replace」这类成熟的搜索替换插件,它能自动处理序列化数据:
- 后台「插件 → 安装插件」,搜索并安装 Better Search Replace,启用。
- 先做数据库备份(下面方法三的第一步),再进入工具页。
- 在「Search for」填旧域名,如
http://old.com;「Replace with」填新域名,如https://new.com。 - 勾选所有表(Select tables 全选),并勾选「Run as dry run」先试跑一次,确认影响行数无误。
- 取消试跑,正式执行替换。完成后清理缓存,前台图片即恢复正常。
方法二:用 WP-CLI 命令行替换(高效可靠)
如果你有 SSH 权限,WP-CLI 的 search-replace 命令是业界公认最稳的方式:
# 进入网站根目录后执行,先试跑(--dry-run 不实际写入)
wp search-replace 'http://old.com' 'https://new.com' --all-tables --dry-run
# 确认无误后正式执行,并顺便处理协议 http -> https
wp search-replace 'http://old.com' 'https://new.com' --all-tables --precise
--all-tables 表示覆盖所有表(包括插件自建表),--precise 会逐个处理并兼顾序列化数据。
方法三:纯数据库 SQL 替换(无插件无 SSH 时)
务必先备份数据库,再操作。用 phpMyAdmin 导出备份后,执行如下语句(表前缀按实际替换):
-- 1. 修正站点地址两项配置
UPDATE wp_options SET option_value = 'https://new.com' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'https://new.com' WHERE option_name = 'home';
-- 2. 替换文章正文中的旧域名
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://old.com', 'https://new.com');
UPDATE wp_posts SET guid = REPLACE(guid, 'http://old.com', 'https://new.com');
-- 3. 替换自定义字段里的图片、链接
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://old.com', 'https://new.com');
SQL 的 REPLACE 不处理序列化数据,所以只对纯文本字段(正文、guid)安全。涉及主题选项的小工具数据,改用方法一或方法二,避免破坏结构。
常见踩坑点
- 直接文本全局替换导致配置错乱。 序列化字符串长度不匹配,反序列化失败后主题设置、菜单可能全部重置,这是最贵的错误。
- 没备份就动手。 替换前一定要导出完整数据库,出问题能回滚,别拿生产库冒险。
- 新旧域名长度不同的坑。 免插件的 SQL 替换在域名长度变化时对序列化项尤其危险,长度一变必崩。
- 没处理 http 与 https 混用。 只替换
old.com却漏了http://与https://两种前缀,仍会有图片裂开。 - 替换后不清缓存。 缓存插件、浏览器、CDN 都可能留着旧地址,替换完要清一遍再看效果。
- 忽略表格、插件自建表。 有些表单、SEO 插件把图片写进自家数据表,
--all-tables或全选表才能覆盖。
总结
迁移后图片不显示、右键一看还是旧域名,本质是数据库里的绝对地址没跟着更新,图片文件本身通常安然无恙。安全替换的关键有两条:一是先备份、后操作,二是用能识别序列化数据的工具,比如 Better Search Replace 插件或 WP-CLI 的 search-replace,只有在纯文本字段上才可以直接用 SQL 的 REPLACE。替换完别忘了清理缓存并顺便统一 http 到 https。判断链接是否仍有漏网之鱼,可以打开一篇文章按 F12,在「网络」面板里筛选出 404 的图片请求,一眼就能看到还有哪些地址没换干净。按这个流程做,WordPress 迁移后图片指向旧域名的批量替换问题就能一次解决,文章的图文呈现也不会再缺图。
