搜索全站
主题 12 分钟阅读

WordPress 附件页处理:重定向到父级文章或图片本身

附件页内容空洞却大量被收录?本文讲清附件页的成因,给出按父级文章重定向、图片直接跳转、无父级时的兜底处理代码,以及服务器层与插件方案的对比。

U
UFO_PF 2019-11-26 · 阅读 12 分钟
Wo 主题
阅读提示
本文约 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。

保姆级实操

  1. 统计现有附件页:先看看库里有多少附件、多少被收录,评估影响范围。
  2. 改插入图片的默认行为:在编辑器里把「链接到」设为「无」或「媒体文件」,从源头减少附件页链接。
  3. 批量清理已有链接:文章内容里指向附件页的 <a> 需要替换成图片文件或去掉链接。
  4. 加重定向:在 template_redirect 上判断 is_attachment(),按父级优先、文件次之的顺序跳转。
  5. 处理无父级的附件:直接跳到 wp_get_attachment_url(),或跳到首页(不推荐,会产生大量指向首页的跳转)。
  6. 保留例外:需要附件页的场景(如摄影站的作品页)用白名单排除。
  7. 验证:用 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;
}

常见踩坑

  1. 在模板文件里调用 wp_safe_redirect():此时已有 HTML 输出,会触发「Cannot modify header information」警告。必须挂在 template_redirect 上。
  2. 用 302 而非 301:搜索引擎不会把权重传给目标页,旧 URL 也移除得慢。永久迁移统一用 301。
  3. 案例:某站做了附件页重定向后,文章页流量反而下降。排查发现 post_parent 大多为 0(图片是从媒体库直接上传的),重定向逻辑把这些图全部 301 到了首页——上千个 URL 指向首页,被判定为异常跳转模式。改成「无父级跳到图片文件本身」后恢复。教训:不要把大量 URL 重定向到首页,这是与 404 处理同样的禁忌。
  4. wp_safe_redirect() 拦截了外部域名:这个函数的「safe」体现在会检查目标域名是否在允许列表内。跳到 CDN 域名时会被拦,需要先用 allowed_redirect_hosts 过滤器放行。
  5. 忘记处理已被收录的旧 URL:重定向只解决访问,已收录的 URL 需要等搜索引擎重新抓取才能移除。可以在 Search Console 提交移除请求加速。
  6. 编辑器默认仍链接到附件页:只做了重定向,新内容还在不断产生附件页链接。在「设置 → 媒体」或使用代码把默认的「链接到」改成「无」。
  7. CDN 域名导致 home_url() 判断失效:判断逻辑里硬编码了 home_url(),图片走 CDN 后匹配不到。用 wp_get_upload_dir() 的 baseurl 判断更通用。
  8. 误伤 PDF 等文档附件:有些站点确实需要让用户访问文档附件页做下载。这类附件按 MIME 类型单独排除,处理方式可参考 主题日期归档是否该保留 里「按内容价值取舍」的思路。

总结

附件页的判断标准是:这个页面是否有独立于图片的文字价值。绝大多数情况下答案是否定的,应当重定向。行动清单:统计附件数量与收录情况 → 把编辑器默认「链接到」改成「无」或「媒体文件」 → 在 template_redirect 上做 301,优先跳父级文章、无父级跳图片文件 → 白名单排除特殊附件 → 用 curl -I 验证状态码与 Location → 提交移除请求加速清理 → 避免任何「跳首页」的兜底。清理完附件页,站点的低质量页面占比会明显下降。顺带可以检查 主题作者页与归档页的 SEO 处理,把同类归档页一并梳理。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。