le monde de crabs (Christophe Cazajus)

Traiter les erreurs HTTP 404 (Not Found)

Les erreurs HTTP 404

Attention Le mécanisme décrit ici n'est testé qu'avec apache Attention

Attention PHP et MySQL nécessaire pour les exemples Attention

Attention Les scripts ont ici l'extension txt, afin qu'ils ne soient pas exécutés sur ce site. Attention

Une des plaies des sites WEB, c'est les erreurs HTTP 404 : « Document non trouvé » ou en anglais « Not Found ». Elles entraînent souvent des désagréments pour les internautes qui suite à cette erreur ont tendance à partir voir ailleurs...

Les erreurs 404 ont 2 raisons principales d'arriver :

Pour les malins, on les laissera face à leurs désagréments, en revanche la première raison peut mériter qu'on s'y intéresse. Cela peut se produire si nous réorganisons notre site ou si nous le déménageons.

Personnaliser la page d'erreur

Cette première solution est très simple, elle va juste permettre de conserver le style de votre site pour signaler une erreur 404 à vos internautes.

Première chose à faire, créer un fichier erreur.html (par exemple) qui reprend les éléments de styles de votre site. Il sera déposer dans le dossier racine de votre site (DocumentRoot pour apache). Par la suite nous allons demander à apache d'afficher cette page à l'aide d'un fichier .htaccess, placé à la racine de votre site :

ErrorDocument 404 /erreur.html

adapter le nom de fichier si nécessaire

Si vous hébergez votre site ou si vous avez la possibilité de configurer apache, cette directive peut être insérée dans les fichiers de configuration.

Travail préparatoire PHP/MySQL pour la suite

 

Les paramètres de connexion

Vous devez adapter les informations de connexion à votre base de données. Nous partons du principe que ce compte aura tous les droits sur la base identifiée.

Le script suivant va être partagé par les autres scripts de cet exemple. Vous pouvez le renommer, mais conserver l'extension .php, qui permet de garder sont contenu invisible aux internautes.

    1 <?php
    2 $db_host = 'localhost' ;
    3 $db_user = 'http404' ;
    4 $db_pass = 'http404' ;
    5 $db_base = 'http404' ;
    6 $db_table = 'rdu' ; // ReDirect Url
    7 ?>

Télécharger http404_param.phpTélécharger http404_param.php

Attention Donnez l'extension PHP à ce fichier Attention

 

Créer la table

Déposer ce script dans le même dossier que le fichier de paramétrage, le supprimer après son exécution.

    1 <?php
    2 header( 'Content-type: text/plain' ) ;
    3 include( 'http404_param.php' ) ;
    4 
    5 $c = mysql_connect( $db_host, $db_user, $db_pass )
    6     or exit( 'mysql_connect: '.mysql_error() ) ;
    7 
    8 mysql_select_db( $db_base )
    9     or exit( 'mysql_select_db: '.mysql_error() ) ;
   10 
   11 // le drop sert dans le cas des mises à jour
   12 $sql = "DROP TABLE IF EXISTS $db_table" ;
   13 mysql_query( $sql ) or exit( "SQL:\n$sql\nERR:\n".mysql_error() ) ;
   14 
   15 // Si les URL sont plus longue : utilisez des champs de type 'TEXT'
   16 $sql = <<<SQL
   17     CREATE TABLE $db_table (
   18         dt DATETIME NOT NULL,
   19         url  VARCHAR(255) NOT NULL,
   20         ref VARCHAR(255) NOT NULL,
   21         INDEX ( dt )
   22         )
   23 SQL;
   24 mysql_query( $sql ) or exit( "SQL:\n$sql\nERR:\n".mysql_error() ) ;
   25 
   26 echo "That's all folk...\n"
   27 ?>

Télécharger http404_table.phpTélécharger http404_table.php

Attention Donnez l'extension PHP à ce fichier Attention

 

Afficher la table

    1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    2 <html>
    3 <head>
    4     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
    5     <title>Listes des erreurs 404</title>
    6 <style>
    7     table { border-collapse: collapse ; border: 2px solid black ; }
    8     td { border: 1px solid black ; padding: 3px 15px ; }
    9 </style>
   10 </head>
   11 <body>
   12 <?php
   13 // adapter le chemin si nécessaire
   14 include( 'http404_param.php' ) ;
   15 
   16 $c = mysql_connect( $db_host, $db_user, $db_pass )
   17     or exit( 'mysql_connect: '.mysql_error() ) ;
   18 
   19 mysql_select_db( $db_base )
   20     or exit( 'mysql_select_db: '.mysql_error() ) ;
   21 
   22 $sql = "SELECT * FROM $db_table ORDER BY dt DESC" ;
   23 $res = mysql_query( $sql ) or exit( "SQL:\n$sql\nERR:\n".mysql_error() ) ;
   24 
   25 echo "<table>\n" ;
   26 while ( $r = mysql_fetch_assoc( $res ) )
   27     {
   28     echo "<tr>";
   29     foreach( $r as $v ) echo "<td>$v</td>" ;
   30     echo "</tr>";
   31     }
   32 echo "</table>\n" ;
   33 ?>
   34 </body>
   35 </html>

Télécharger http404_list.phpTélécharger http404_list.php

Attention Donnez l'extension PHP à ce fichier Attention

 

Bonus : créer la base de données

Voici les quelques commandes SQL qui permettront de créer la base de données avec le compte d'administration de MySQL :

mysql> create database http404 ;
Query OK, 1 row affected (0,03 sec)
mysql> grant all on http404.* to http404 identified by 'http404' ;
Query OK, 0 rows affected (0,03 sec)
mysql> 

Du PHP pour tracer les 404

Nous allons afficher une page qui répond à la charte graphique de notre site, celle définie au précédemment. Puis nous enregistrons dans une base l'adresse qui a généré l'erreur avec l'adresse de la page contenant le lien, lorsqu'elle est disponible.

Pour cela, nous allons utiliser 2 variables super-globales du PHP issues d'apache : REQUEST_URI et HTTP_REFERER.

La variable « REQUEST_URI » nous donne le chemin du fichier qui a déclenché l'erreur HTTP 404. Il s'agit du chemin de fichier commençant par « / », par rapport à la valeur de la directive DocumentRoot.

La variable « HTTP_REFERER » indique, si elle est disponible l'URL absolue de la page contenant le lien.

    1 <?php
    2 // On redirige vers la page d'erreur (adapter si nécessaire)
    3 header( 'Location: /erreur.html' ) ;
    4 
    5 // adapter le chemin si nécessaire
    6 include( 'http404_param.php' ) ;
    7 
    8 // Les erreurs SQL sont ignorées
    9 @$c = mysql_connect( $db_host, $db_user, $db_pass ) or exit() ;
   10 @mysql_select_db( $db_base ) or exit() ;
   11 $rdu = 'inconnu' ; $ref = 'inconnu' ;
   12 if ( array_key_exists( 'REQUEST_URI', $_SERVER ) )
   13     $rdu = addslashes( $_SERVER['REQUEST_URI'] ) ;
   14 if ( array_key_exists( 'HTTP_REFERER', $_SERVER ) )
   15     $ref = addslashes( $_SERVER['HTTP_REFERER'] ) ;
   16 @$sql = "INSERT INTO rdu VALUES( NOW(), '$rdu', '$ref' )" ;
   17 mysql_query( $sql ) ;
   18 mysql_close( $c ) ;
   19 ?>

Télécharger http404_err.phpTélécharger http404_err.php

Attention Donnez l'extension PHP à ce fichier Attention

 

N'oubliez pas d'adapter le .htaccess :

ErrorDocument 404 /http404_err.php
 

Passer par une redirection va permettre de faire disparaître les code d'erreur 404 et donner un 302 : « Found » dont une signification pour les moteurs de recherche est « déplacé on ne sait pas pourquoi ». Dans les log d'erreurs d'apache, l'entrée présentant le défaut de page reste inscrite.

Une adaptation CGI facilement réalisable, les deux variables faisant parti de l'environnement du processus.

Ajouter des redirections

J'ai eu des soucis avec des forums qui écourtaient les URL placées dans les posts. J'ai eu donc pendant un certain temps des erreurs 404 en paquets.

Il peut être intéressant de rediriger une erreur HTTP 404 vers une page existante du site. La redirection devient donc permanente : HTTP 301. L'outil checklink du W3C recommande au webmaster de corriger les liens fournissant des codes HTTP 301, en les remplaçant par le lien correct.

Nous allons modifier notre script d'interception d'erreur pour mettre en place des redirections permanentes sur des URL partielles.

    1 <?php
    2 // traite les urls partielles
    3 @$uri = rawurlencode( $_SERVER['REQUEST_URI'] ) ;
    4 $urls = array(
    5     '/index' => '/index.html',
    6     '/i' => '/index.html'
    7     ) ;
    8 foreach( $urls as $rdu => $ref )
    9     if ( rawurlencode( $rdu ) == $uri )
   10         {
   11         header("HTTP/1.1 301 Moved Permanently");
   12         header( 'Location: '.$ref ) ;
   13         exit() ; // on logue plus ces erreurs
   14         }
   15 // On redirige vers la page d'erreur (adapter si nécessaire)
   16 header( 'Location: /erreur.html' ) ;
   17 
   18 // adapter le chemin si necessaire
   19 include( 'http404_param.php' ) ;
   20 
   21 // Les erreurs SQL sont ignorées
   22 @$c = mysql_connect( $db_host, $db_user, $db_pass ) or exit() ;
   23 @mysql_select_db( $db_base ) or exit() ;
   24 $rdu = 'inconnu' ; $ref = 'inconnu' ;
   25 if ( array_key_exists( 'REQUEST_URI', $_SERVER ) )
   26     $rdu = addslashes( $_SERVER['REQUEST_URI'] ) ;
   27 if ( array_key_exists( 'HTTP_REFERER', $_SERVER ) )
   28     $ref = addslashes( $_SERVER['HTTP_REFERER'] ) ;
   29 @$sql = "INSERT INTO rdu VALUES( NOW(), '$rdu', '$ref' )" ;
   30 mysql_query( $sql ) ;
   31 mysql_close( $c ) ;
   32 ?>

Télécharger http404_redirect.phpTélécharger http404_redirect.php

Attention Donnez l'extension PHP à ce fichier Attention

 

N'oubliez pas d'adapter le .htaccess :

ErrorDocument 404 /http404_redirect.php

Les RewriteRule d'apache

Nous pouvons gérer la redirection des URL à l'aide des règles de réécriture des URL fourni par apache : les RewriteRule.

Les RewriteRule s'inscrivent dans le .htaccess. Utilisant les expressions régulières, leur puissance est proportionnelle à leur complexité...

Dans notre cas, elle peuvent être intéressante, car les expressions régulières sont simples, donc pour nos deux URL partielles, il faut que le .htaccess ressemble à ceci :

RewriteEngine On
RewriteRule ^i$ /index.html [R=permanent]
RewriteRule ^index$ /index.html [R=permanent]

ErrorDocument 404 /http404_err.php

On utilise /http404_err.php qui enregistre les URL en erreur HTTP 404.

En conclusion

Comme tout problème que nous pouvons rencontrer, les solutions et les traitements associés n'ont comme limite que votre imagination.

L'utilité de cette étude est double : elle permet de garder un internaute sur vos pages et elle donne une meilleure consistance à votre site vue des outils qui parcourent votre site pour le référencement.

Renseignez-vous sur les brevets logiciels en Europe :

NoSoftWarePatents.com (en français)

Les images représentant des sociétes, des associations ou des marques restent associées, par un lien, à ces sociétés, associations ou marques. Elles ne signifie en rien que ces sociétés, associations ou marques soutiennent ce site.

Sauf précisions contraire, le contenu de ce site est mis à disposition sous un contrat Creative Commons.

Les informations fournies le sont sans aucune garantie. L'auteur ne pourra être tenu responsable de leurs utilisations.

De par l'utilisation du HTML 4.01 Strict et des CSS 2.1, le monde de crabs sera correctement vu avec les navigateurs respectant ces normes, Mozilla ou FireFox par exemple.

Site : Le Monde de Crabs
Titre : Traiter les erreurs HTTP 404 (Not Found)
Date du document : 07/09/2008
Auteur : Christophe Cazajus
Mail : crabs(mettre le @)crabs-world.com
ou utiliser ce formulaire de contact
Mots-clé : crabs, monde, francais, francophone, français, http, html, php, ErrorDocument, 404, location, redirection, apache, htaccess
Description : Comment tracer et rediriger un navigateur ou un spider vers la bonne page suite à une erreur HTTP 404 avec apache et un .htaccess
Validation : html, css
The Linux Counter
Info iconelvis iconbash iconphp icongimp iconpovray iconxml iconxslt iconcss iconhtml icon
Slackware Linux
Creative Commons License

Le calendrier et les scores du Stade Toulousain sont accessibles sur cette page : Le monde de crabs et le Stade Toulousain.

Crabs's World : English Section