如何在WordPress上强制使用404


40

我需要根据条件在某些帖子上强制使用404。我设法做到了(尽管我不知道我做对的方法是否正确),而且我正在404.php按预期加载模板。

我的代码:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    include( get_query_template( '404' ) );
    exit; # so that the normal page isn't loaded after the 404 page
  }
}

add_action( 'template_redirect', 'rr_404_my_event', 1 );

来自此相关问题的代码2- 同样的问题:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    global $wp_query;
    $wp_query->set_404();
  }
}

add_action( 'wp', 'rr_404_my_event' );

我的问题:

虽然看起来不错,但是200 OK如果检查“网络”选项卡,我会得到一个状态。由于这是一种状态200,恐怕搜索引擎也可能会将这些页面编入索引。

预期的行为:

我希望404 Not Found发送状态。


来自相关问题: wordpress.stackexchange.com/questions/73738/…–您读过吗?
fuxia

是的,我仍然200对此保持现状。
Rikesh

Answers:


50

您可以尝试使用Wordpress函数status_header()添加HTTP/1.1 404 Not Found标题;

因此,您的代码2示例将是:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    global $wp_query;
    $wp_query->set_404();
    status_header(404);
  }
}
add_action( 'wp', 'rr_404_my_event' );

例如,此部分使用此功能:

function handle_404() {
    ...cut...
    // Guess it's time to 404.
    $wp_query->set_404();
    status_header( 404 );
    nocache_headers();
    ...cut...
}

wp/wp-includes/class-wp.php

因此,除了您的代码外,请尝试使用此修改后的Code 2示例template_include


Code 2您发布的代码片段效果很好。该set_header()是少了什么。
Rikesh

您指的是@birgire set_header()HTTP/1.1 404 Not Found但已status_header()在代码中使用?
henrywright 2014年

@henrywright那里看起来像是一个错字,我更新了答案,谢谢;-)
birgire

15

这段代码对我有用:

add_action('wp','force_404');
函数force_404(){
    全局$ wp_query; // $ posts(如果需要)
    if(is_page()){//您的条件
        status_header(404);
        nocache_headers();
        包括(get_query_template('404'));
        死();
    }
}

便利。我正在检查自定义查询参数,因此我没有使用该操作,但这在我的插件类中提供了一个非常有用的方法。
约翰·里德

2
添加以下内容以修复页面标题:global $wp_query; $wp_query->is_404 = true;
developerbmw

2

我不建议强制使用404。

如果您担心搜索引擎,为什么不只在这些页面上执行“无索引,无关注”的元数据并使用robots.txt阻止它呢?

这可能是阻止内容被查看的更好方法

add_filter( 'template_include', 'nifty_block_content', 99 );

function nifty_block_content( $template ) {
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
        $template = locate_template( array( 'nifty-block-content.php' ) );
     }
    return $template;
}

您可能也可以使用此方法进行加载,404.php但是我认为使用页面模板可能是更好的选择。

资源


非常感谢您提供的链接,我将改为使用locate_template()。我认为这robots.txt.不是防止索引编制的保证方法。一些搜索引擎可能仍会选择该页面。我确实希望页面看起来像普通的404页面。另外,帖子将被动态添加,编辑robots.txt文件将增加更多麻烦。
Rikesh

1

我的解决方案:

add_action( 'wp', 'my_404' );
function my_404() 
{
    if ( is_404() ) 
    {
        header("Status: 404 Not Found");
        $GLOBALS['wp_query']->set_404();
        status_header(404);
        nocache_headers();
        //var_dump(getallheaders()); var_dump(headers_list()); die();
    }
}

1
错误重定向对于您的页面排名非常糟糕。只需在与错误请求相同的位置显示模板即可。当您执行此操作时,将首先设置404,然后重定向将其更改为301或302,然后重定向到返回200的页面。搜索引擎将其索引为有效页面,显然是OP所说的他不想要的。
mopsyd

0

状态代码在HTTP请求的标头中发送。您当前的函数已被钩入一个钩子,该钩子将被调用为时已晚。

您应该尝试使函数rr_404_my_event()生效send_headers

我不确定在那个时候是否甚至可以检查Post ID,但是可以尝试一下:

add_action( 'send_headers', 'rr_404_my_event' );
function rr_404_my_event() {
    global $post;
    if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
        include( get_query_template( '404' ) );
        header('HTTP/1.0 404 Not Found');
        exit; 
    }
}

我从您的代码中纠正了一些语法错误。我什至没有让我的404模板加载。
Rikesh

也许,404.php您可以在其中加载其他内容header.php,例如<?php get_header('404'); ?>load header-404.php。在该标题中,您将header('HTTP/1.0 404 Not Found');<head>部分中添加。
Marc Dingena

0

我想分享使用标记解决方案的方式

function fail_safe_for_authors() {
    if ((is_user_logged_in()) && (is_author()) && ($_COOKIE["user_role"] !== "administrator")) {
            global $wp_query;
            $wp_query->set_404();
            status_header(404);
        }
}
add_action("wp", "fail_safe_for_authors");

我这样做是为了将所有用户类型管理员分开,在此项目中,只有管理员才能看到author.php页面。

我希望它可以帮助其他人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.