本文约 4,721 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:图片自己生成了一个页面,还被收录了几百条
在媒体库上传一张图,WordPress 会给它创建一个「附件」文章类型,并生成一个可访问的地址,形如 https://example.com/2024/05/screenshot-2/。这个页面默认显示一张图、一个标题,几乎没有文字。如果你的文章里图片链接到了「附件页」(插入媒体时「链接到」选了「附件页面」),访客点图就会进到这个空荡荡的页面,然后关掉。
更麻烦的是收录:这类页面数量随图片数量线性增长,几百张图就是几百个低质量页面。Search Console 里经常能看到它们占据了「已收录」的相当比例,而点击量全是 0。Google 也多次在文档里提到,图片附件页属于应当避免索引的内容类型。
处理方式很明确:把附件页重定向到「有意义的页面」——优先是图片的父级文章,没有父级就直接重定向到图片文件本身。本文给出纯代码实现,并说明服务器层和插件方案的取舍。
原理分析:附件页从哪来,模板如何选
| 成因 | 说明 |
|---|---|
| 「链接到:附件页面」 | 插入图片时默认或手动选择,生成站内链接 |
| 直接访问附件 URL | 附件本身是可访问的文章类型 |
主题输出 wp_get_attachment_link() |
链接指向附件页而非图片文件 |
附件页的模板优先级是 image.php(图片类)→ single.php → singular.php → index.php,更精确的是 image-{type}.php / attachment-{type}.php 这类 MIME 类型模板。多数主题没有专门模板,就落到通用单页模板上,于是页面长得像一篇「没有正文的文章」。
重定向的时机必须选在 template_redirect 钩子上:此时主查询已经完成,可以准确判断 is_attachment(),且还没有输出任何 HTML,可以安全发送 Location 头。如果晚于这个时机(比如在模板文件里)再调用 wp_safe_redirect(),会因为已有输出而报「headers already sent」。
父级关系存在 wp_posts.post_parent 字段里,用 wp_get_post_parent_id() 或 get_post_field( 'post_parent' ) 都能取到。要注意的是,从媒体库直接上传的图片 post_parent 为 0,只有在文章编辑页里上传的才会被挂到该文章下——这也是「有些图能重定向到文章、有些不能」的原因。
重定向状态码的选择:这类「永久搬家」用 301 更合适,能让搜索引擎把权重传递给目标页,并逐步移除旧的附件页。临时场景才用 302。
保姆级实操
- 统计现有附件页:先看看库里有多少附件、多少被收录,评估影响范围。
- 改插入图片的默认行为:在编辑器里把「链接到」设为「无」或「媒体文件」,从源头减少附件页链接。
- 批量清理已有链接:文章内容里指向附件页的
<a>需要替换成图片文件或去掉链接。 - 加重定向:在
template_redirect上判断is_attachment(),按父级优先、文件次之的顺序跳转。 - 处理无父级的附件:直接跳到
wp_get_attachment_url(),或跳到首页(不推荐,会产生大量指向首页的跳转)。 - 保留例外:需要附件页的场景(如摄影站的作品页)用白名单排除。
- 验证:用
curl -I检查返回 301 且 Location 正确。
<?php
// 子主题 functions.php
add_action( 'template_redirect', 'mimangfei_redirect_attachment_pages', 1 );
function mimangfei_redirect_attachment_pages() {
if ( ! is_attachment() ) {
return;
}
$attachment_id = get_queried_object_id();
if ( ! $attachment_id ) {
return;
}
// 白名单:需要保留附件页的特殊场景,用 attachment_id 排除
$keep = apply_filters( 'mimangfei_keep_attachment_ids', array() );
if ( in_array( $attachment_id, (array) $keep, true ) ) {
return;
}
$parent_id = (int) wp_get_post_parent_id( $attachment_id );
if ( $parent_id > 0 ) {
$target = get_permalink( $parent_id );
} else {
// 没有父级文章:跳到文件本身
$target = wp_get_attachment_url( $attachment_id );
}
if ( ! $target ) {
$target = home_url( '/' );
}
wp_safe_redirect( $target, 301 );
exit;
}
<?php
// 顺手把正文里指向附件页的链接替换成图片文件,减少无效内链
add_filter( 'the_content', 'mimangfei_replace_attachment_links' );
function mimangfei_replace_attachment_links( $content ) {
if ( ! is_single() && ! is_page() ) {
return $content;
}
$upload_dir = wp_get_upload_dir();
$content = preg_replace_callback(
'#<a[^>]+href=["\'](' . preg_quote( home_url( '/' ), '#' ) . '[^\'"]+?)["\'][^>]*>(<img[^>]+>)</a>#i',
function ( $matches ) use ( $upload_dir ) {
$href = $matches[1];
$img = $matches[2];
if ( preg_match( '#src=["\']([^\'"]+)["\']#i', $img, $src ) ) {
// 链接地址与图片地址同源时,直接把外链换成图片文件地址
if ( false !== strpos( $src[1], $upload_dir['baseurl'] ) ) {
return '<a href="' . esc_url( $src[1] ) . '">' . $img . '</a>';
}
}
return $matches[0];
},
$content
);
return $content;
}
-- 统计附件数量与有父级的比例,评估影响范围
SELECT
COUNT(*) AS total,
SUM( CASE WHEN post_parent > 0 THEN 1 ELSE 0 END ) AS with_parent
FROM wp_posts
WHERE post_type = 'attachment';
# 服务器层方案:直接把 /2024/05/ 这类日期型附件 URL 重写到图片目录
# 仅在确认附件页均已无用时使用,优先级高于 PHP 层
location ~ ^/\d{4}/\d{2}/ {
try_files $uri $uri/ /index.php?$args;
}
常见踩坑
- 在模板文件里调用
wp_safe_redirect():此时已有 HTML 输出,会触发「Cannot modify header information」警告。必须挂在template_redirect上。 - 用 302 而非 301:搜索引擎不会把权重传给目标页,旧 URL 也移除得慢。永久迁移统一用 301。
- 案例:某站做了附件页重定向后,文章页流量反而下降。排查发现
post_parent大多为 0(图片是从媒体库直接上传的),重定向逻辑把这些图全部 301 到了首页——上千个 URL 指向首页,被判定为异常跳转模式。改成「无父级跳到图片文件本身」后恢复。教训:不要把大量 URL 重定向到首页,这是与 404 处理同样的禁忌。 wp_safe_redirect()拦截了外部域名:这个函数的「safe」体现在会检查目标域名是否在允许列表内。跳到 CDN 域名时会被拦,需要先用allowed_redirect_hosts过滤器放行。- 忘记处理已被收录的旧 URL:重定向只解决访问,已收录的 URL 需要等搜索引擎重新抓取才能移除。可以在 Search Console 提交移除请求加速。
- 编辑器默认仍链接到附件页:只做了重定向,新内容还在不断产生附件页链接。在「设置 → 媒体」或使用代码把默认的「链接到」改成「无」。
- CDN 域名导致
home_url()判断失效:判断逻辑里硬编码了home_url(),图片走 CDN 后匹配不到。用wp_get_upload_dir()的baseurl判断更通用。 - 误伤 PDF 等文档附件:有些站点确实需要让用户访问文档附件页做下载。这类附件按 MIME 类型单独排除,处理方式可参考
主题日期归档是否该保留里「按内容价值取舍」的思路。
总结
附件页的判断标准是:这个页面是否有独立于图片的文字价值。绝大多数情况下答案是否定的,应当重定向。行动清单:统计附件数量与收录情况 → 把编辑器默认「链接到」改成「无」或「媒体文件」 → 在 template_redirect 上做 301,优先跳父级文章、无父级跳图片文件 → 白名单排除特殊附件 → 用 curl -I 验证状态码与 Location → 提交移除请求加速清理 → 避免任何「跳首页」的兜底。清理完附件页,站点的低质量页面占比会明显下降。顺带可以检查 主题作者页与归档页的 SEO 处理,把同类归档页一并梳理。
