Pages introuvables : comment détecter les erreurs 404

Publié le 9 février 2011 - Developpement Web. Tags :

Dans la série je traque les éventuelles erreurs générées sur mon site internet, voici un sujet qui fâche : les pages introuvables. Couramment appelées ‘erreurs 404′, ces pages sont un véritable fléau, un caillou pouvant ruiner un engrenage parfaitement huilé. Et les causes pouvant être multiples et particulièrement vicieuses (liens relatifs de répertoires virtuels mal interprétés sur certains navigateurs), plus ou moins aucun webmaster n’est épargné. Qu’il s’agisse d’une faute de frappe dans une balise href , de pages effacées ou accessibles à une autre url sans redirection 301, dans tous les cas l’image renvoyée par le site n’est pas très bonne. Pire : c’est même pénalisant pour votre positionnement sur les moteurs de recherche. Le problème, c’est qu’il n’est pas forcément si facile que cela de détecter toutes ces 404 générées sur son site.

Ici, pas question de vous présenter différentes pages d’erreurs personnalisées que l’on peut trouver ici ou là, ni de vous présenter les différentes façon de traquer ces pages/fichiers introuvables. Sachez simplement que différentes pistes de détection s’offrent à vous, telle que la consultation des logs de votre serveur, l’exploration des erreurs signalées dans Google Webmaster tools, ou encore l’utilisation de programmes spécifiques comme Xenu, LinkExaminer ou des vérificateurs de liens morts en ligne.

En ce qui me concerne, j’utilise une approche beaucoup plus directe et efficace (entre terme de temps/performances) : une solution simpliste en PHP/MySQL. Le concept : utiliser votre page d’erreur 404 pour enregistrer vous-même les problèmes rencontrés.

Avant de commencer, le prérequis de cette installation est d’avoir une redirection des erreurs 404 sur une page spécifique. Si ce n’est pas déjà fait, ajoutez ceci dans votre fichier .htaccess disponible à la racine de votre serveur:

ErrorDocument 404 /404.php

Pensez au passage à renvoyer un header 404 (cf. ci-dessous), ou votre page d’erreur 404.php renverra un code 200 (OK), ce qui est incorrect.

header("HTTP/1.0 404 Not Found");

Ceci étant dit, attaquons nous maintenant au script à proprement parler. Les données qui vont être primordiales à enregistrer sont les suivantes :

  • pages à l’origine des erreurs 404,
  • pages introuvables

(En complément, je logge aussi les user agents, etc – mais c’est facultatif)

Passons aux choses sérieuses : pour enregistrer les erreurs 404 vous allez avoir besoin d’une table, de ce type :

CREATE TABLE IF NOT EXISTS `erreurs_404` (
`er_id` int(8) NOT NULL auto_increment,
`er_from` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL,
`er_to` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL,
`er_ip` varchar(15) character set utf8 collate utf8_unicode_ci NOT NULL,
`er_date` datetime NOT NULL,
PRIMARY KEY  (`er_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;

Ceci étant fait, nous allons maintenant mettre en place le script de détection des erreurs 404 (page 404.php donc) :

$to = $_SERVER['REQUEST_URI'];
$from = $_SERVER['HTTP_REFERER'];
$ip = $_SERVER['REMOTE_ADDR'];
 
if(!empty($from))  { //Sinon la détection est inutile
mysql_query("INSERT INTO erreurs_404 VALUES('', '".mysql_real_escape_string($from)."', '".mysql_real_escape_string($to)."', '".mysql_real_escape_string($ip)."', now())");
}
}

A noter qu’il est possible (et préférable) d’utiliser une fonction pour la détection des IPs, puisque que c’est une vérification souvent récurrente sur un site, et qu’il est souvent nécessaire d’ajouter des conditions de détection un peu plus efficaces (HTTP_X_FORWARDED_FOR, etc.).

Bien sûr c’est assez brut, et à ce stade pour analyser vos erreurs 404 vous allez devoir utiliser phpMyAdmin. Un petite requête et une boucle basique devrait suffire, à moins que vous n’ayez enregistré des milliers d’erreurs, auquel cas une pagination ne serait pas de trop. Mais grosso modo voilà l’idée :

$get_erreurs = mysql_query("SELECT * FROM erreurs_404 ORDER BY er_date DESC");
while ($erreur = mysql_fetch_assoc($get_erreurs)) {
echo ''.htmlentities($erreur['er_date']).' - '.htmlentities($erreur['er_from']).' ->
'.htmlentities($erreur['er_to']).'
';
}

Et voilà pour une détection des erreurs 404 indépendante, simple et efficace.