404 on paginated blog pages

时间:2021-02-05 作者:Jason Pierson

我们正在运行WP 5.6和Beaver Builder 2.4.1.3(Pro)。这是一个多站点安装,我们在主站点上有问题。

我们的博客主页加载得很好:https://www.awana.org/blog

但后续页面返回404:https://www.awana.org/blog?page=2https://www.awana.org/blog?page=3https://www.awana.org/blog?page=4等等根据博客主页底部的文字,我们应该有60页的帖子。

我打开了WP仪表板,查看了帖子。果然,这些帖子确实存在。

在我们的一个沙盒中,我停用了除Beaver Builder、高级自定义字段和自定义插件之外的所有插件。我无法停用最后两个b/c。如果没有高级自定义字段,网站上的任何页面都不会加载,如果没有自定义插件,博客主页也不会加载。自定义插件钩住init操作,从rss提要获取所有博客帖子,创建html以显示帖子列表,并将其返回到Beaver Builder页面(博客主页)使用的快捷码。我也转到了第二十二个主题。我还是有同样的问题。

我们最近将WP从5.3.2升级到了5.6。这在我们升级之前就起作用了。在调试这个问题时,我注意到一些核心WP代码发生了更改。wp中包括/类wp。php中,handle\\u 404 fn的一个块如5.3.2所示:

// Never 404 for the admin, robots, or if we found posts.
if ( is_admin() || is_robots() || $wp_query->posts ) {

    $success = true;
    if ( is_singular() ) {
        $p = false;

        if ( $wp_query->post instanceof WP_Post ) {
            $p = clone $wp_query->post;
        }

        // Only set X-Pingback for single posts that allow pings.
        if ( $p && pings_open( $p ) && ! headers_sent() ) {
            header( \'X-Pingback: \' . get_bloginfo( \'pingback_url\', \'display\' ) );
        }

        // check for paged content that exceeds the max number of pages
        $next = \'<!--nextpage-->\';
        if ( $p && false !== strpos( $p->post_content, $next ) && ! empty( $this->query_vars[\'page\'] ) ) {
            $page    = trim( $this->query_vars[\'page\'], \'/\' );
            $success = (int) $page <= ( substr_count( $p->post_content, $next ) + 1 );
        }
    }

    if ( $success ) {
        status_header( 200 );
        return;
    }
}
在5.6中,更改为:

$set_404 = true;

// Never 404 for the admin, robots, or favicon.
if ( is_admin() || is_robots() || is_favicon() ) {
    $set_404 = false;

    // If posts were found, check for paged content.
} elseif ( $wp_query->posts ) {
    $content_found = true;

    if ( is_singular() ) {
        $post = isset( $wp_query->post ) ? $wp_query->post : null;

        // Only set X-Pingback for single posts that allow pings.
        if ( $post && pings_open( $post ) && ! headers_sent() ) {
            header( \'X-Pingback: \' . get_bloginfo( \'pingback_url\', \'display\' ) );
        }

        // Check for paged content that exceeds the max number of pages.
        $next = \'<!--nextpage-->\';
        if ( $post && ! empty( $this->query_vars[\'page\'] ) ) {
            // Check if content is actually intended to be paged.
            if ( false !== strpos( $post->post_content, $next ) ) {
                $page          = trim( $this->query_vars[\'page\'], \'/\' );
                $content_found = (int) $page <= ( substr_count( $post->post_content, $next ) + 1 );
            } else {
                $content_found = false;
            }
        }
    }

    // The posts page does not support the <!--nextpage--> pagination.
    if ( $wp_query->is_posts_page && ! empty( $this->query_vars[\'page\'] ) ) {
        $content_found = false;
    }

    if ( $content_found ) {
        $set_404 = false;
    }

    // We will 404 for paged queries, as no posts were found.
}
我们没有<!--nextpage--> 在博客页面的post\\u内容中。这不是5.3.2和以前版本b/c中的问题$success 已设置为true(在上面的代码中)。所以如果<!--nextpage--> 不在post\\U内容中,无论如何都会返回true,并且没有404错误。由于情况不再如此,我们收到了404。

博客页面上post\\u内容的值为:

<!-- wp:fl-builder/layout -->
<h1></h1>
[cats-dropdown]
[aggregated_posts]
<!-- /wp:fl-builder/layout -->
我尝试将其改为:

<!-- wp:fl-builder/layout -->
<h1></h1>
[cats-dropdown]
[aggregated_posts]
<!--nextpage-->
<!-- /wp:fl-builder/layout -->
这适用于第2页,但不适用于第3页、第4页等。它类似于以下代码行:

$content_found = (int) $page <= ( substr_count( $post->post_content, $next ) + 1 );
在上面的块中,期望<!--nextpage--> 在post\\u内容中打印的次数与页面数相同。如果有60页<!--nextpage--> 必须打印60次。

我想有更好的方法来显示第2、3、4页等,而不是复制和粘贴<!--nextpage--> 进入post\\u内容60次,然后在有60、61、62等多个页面时要记得更新。有什么想法吗?

1 个回复
SO网友:vfranchi

我设法解决了这个问题。我最近将我的网站更新到Wordpress 5.7,除主页外,每个页面都出现404个错误。经过多次调试,我发现wp-includes/class-wp.php 正在设置is_404 缺少注释导致变量<!--nextpage-->$post->post_content. (第694行)

我尝试禁用网站上的所有插件。使用二十一主题。重新保存永久链接。创建新页面以测试它。什么都没用。所以我在我的主题function.php:

add_filter("pre_handle_404", "no_nextpage_fix", 10, 2);
function no_nextpage_fix($return, $wp_query)
{
    $next = \'<!--nextpage-->\';
    $post = isset( $wp_query->post ) ? $wp_query->post : null;
    if ($post && false === strpos( $post->post_content, $next ))
    {
        $post->post_content .= $next;
    }
    return $return;
}