Cum să forțezi o eroare 404 în WordPress

22 mar. 2013, 08:53:33
Vizualizări: 92K
Voturi: 53

Am nevoie să forțez o eroare 404 pentru unele postări bazate pe anumite condiții. Am reușit să fac acest lucru (deși nu sunt sigur dacă am făcut-o corect) și template-ul meu 404.php se încarcă așa cum mă așteptam.

Codul meu:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    include( get_query_template( '404' ) );
    exit; # pentru a preveni încărcarea paginii normale după pagina 404
  }
}

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

Codul 2 din această întrebare înrudită - aceeași problemă:

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' );

Problema mea:

Deși pare să funcționeze, primesc un status 200 OK când verific în tab-ul Network. Deoarece este un status 200, mă tem că motoarele de căutare ar putea indexa aceste pagini.

Comportamentul așteptat:

Vreau ca serverul să returneze un status 404 Not Found.

2
Comentarii

Din întrebările conexe: http://wordpress.stackexchange.com/questions/73738/how-do-i-programmatically-generate-a-404 – ai citit asta?

fuxia fuxia
22 mar. 2013 11:34:50

Da, încă primesc un status 200 cu asta.

RRikesh RRikesh
22 mar. 2013 11:40:47
Toate răspunsurile la întrebare 7
3
78

Ai putea încerca funcția WordPress status_header() pentru a adăuga antetul HTTP/1.1 404 Not Found;

Deci exemplul tău Code 2 ar arăta astfel:

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' );

Această funcție este folosită de exemplu în această porțiune:

function handle_404() {
    ...tăiat...
    // Presupunem că e momentul pentru 404.
    $wp_query->set_404();
    status_header( 404 );
    nocache_headers();
    ...tăiat...
}

din clasa wp din fișierul /wp-includes/class-wp.php.

Deci încearcă să folosești acest exemplu modificat Code 2 în plus față de codul tău template_include.

24 mar. 2013 20:17:28
Comentarii

Fragmentul de cod Code 2 pe care l-ai postat funcționează perfect. set_header() era ceea ce lipsea.

RRikesh RRikesh
25 mar. 2013 07:11:42

@birgire te referi la set_header() pentru a adăuga HTTP/1.1 404 Not Found dar ai folosit status_header() în codul tău?

henrywright henrywright
8 sept. 2014 16:08:48

@henrywright se pare că e o greșeală de tipar acolo, am actualizat răspunsul, mulțumesc ;-)

birgire birgire
8 sept. 2014 16:45:24
2
23

Acest cod a funcționat pentru mine:

add_action( 'wp', 'force_404' );
function force_404() {
    global $wp_query; //$posts (dacă este necesar)
    if(is_page()){ // condiția ta
        status_header( 404 );
        nocache_headers();
        include( get_query_template( '404' ) );
        die();
    }
}
24 mar. 2013 20:42:04
Comentarii

Folositor. Verific parametri personalizați în interogare, așa că nu folosesc acțiunea, dar este o metodă foarte utilă în clasa mea de plugin.

John Reid John Reid
17 oct. 2014 11:26:56

Adaugă următoarele pentru a repara titlul paginii: global $wp_query; $wp_query->is_404 = true;

brettwhiteman brettwhiteman
25 feb. 2016 00:18:54
0

Cea mai robustă metodă pe care am găsit-o pentru a realiza acest lucru este să o faci în filtrul template_include, astfel:

function wpse91900_force_404(string $template): string {
    if ($some_condition) {
        global $wp_query;

        $wp_query->set_404();
        status_header(404);
        nocache_headers();

        $template = get_404_template();
    }

    return $template;
}
add_filter("template_include", "wpse91900_force_404");
1 feb. 2022 17:33:22
1

Nu aș recomanda forțarea unei erori 404.

Dacă ești îngrijorat de motoarele de căutare, de ce nu adaugi pur și simplu un meta tag "no-index,no-follow" pe acele pagini și le blochezi cu robots.txt?

Aceasta ar putea fi o metodă mai bună de a bloca vizualizarea conținutului

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;
}

Ai putea probabil folosi și această metodă pentru a încărca 404.php dar cred că utilizarea unui template de pagină ar fi o opțiune mai bună.

sursă

22 mar. 2013 10:47:21
Comentarii

Mulțumesc mult pentru link, voi trece la utilizarea locate_template() în loc. Cred că robots.txt nu este o metodă garantată pentru protecția împotriva indexării. Unele motoare de căutare ar putea totuși prelua pagina. Vreau ca pagina să arate ca o pagină normală de 404. De asemenea, postările vor fi adăugate dinamic, iar editarea fișierului robots.txt va aduce probleme suplimentare.

RRikesh RRikesh
22 mar. 2013 11:23:15
0

Am vrut să împărtășesc modul în care am folosit soluția marcată

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");

Am făcut asta pentru a separa toate tipurile de utilizatori de administrator, în acest proiect, doar adminul poate vedea pagina author.php.

Sper că ar putea ajuta pe altcineva.

4 oct. 2019 21:20:53
1

Soluția mea:

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();
    }
}
21 iul. 2014 15:24:48
Comentarii

Redirecționarea în caz de erori este dezastruoasă pentru poziționarea paginii tale. Pur și simplu afișează un șablon în aceeași locație ca și cererea incorectă. Ceea ce se va întâmpla atunci când faci asta este că inițial setezi un cod 404, iar apoi redirecționarea îl schimbă într-un 301 sau 302, care apoi redirecționează către o pagină care returnează un 200. Aceasta va fi apoi indexată de motoarele de căutare ca o pagină validă, ceea ce este exact ceea ce OP a spus că nu dorește.

mopsyd mopsyd
15 mar. 2018 03:43:12
3

Codurile de stare sunt trimise în anteturile cererilor HTTP. Funcția ta curentă este conectată la un cârlig care va fi apelat prea târziu.

Ar trebui să încerci să conectezi funcția ta rr_404_my_event() la acțiunea send_headers.

Nu sunt sigur dacă în acel moment este posibil să verifici ID-ul postării, dar încearcă asta:

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; 
    }
}
22 mar. 2013 12:42:35
Comentarii

Am corectat câteva erori de sintaxă din codurile tale. Nici măcar nu reușesc să încarc șablonul meu 404 cu asta.

RRikesh RRikesh
22 mar. 2013 12:48:41

Poate că în 404.php ai putea încărca un header.php diferit, de exemplu <?php get_header('404'); ?> pentru a încărca header-404.php. În acel header, ai adăuga header('HTTP/1.0 404 Not Found'); în secțiunea <head>.

Marc Dingena Marc Dingena
22 mar. 2013 13:07:07

@MarcDingena Cred că trebuie să pui linia header() înaintea celei în care afișezi conținutul șablonului, altfel vei obține pagina corectă de șablon afișată, dar codul real HTTP va fi în continuare 200.

David Wolf David Wolf
26 feb. 2022 22:28:16