Los errores HTTP se ven bastante seguido, pueden suceder en cualquier sitio, en cualquier momento. El sitio falla, alguien copia mal un enlace que le pasa a un amigo, alguien escribe mal la dirección a la que quiere ir. Incluso puede pasar que un motor de búsqueda tenga un enlace viejo en su índice.
Se podría decir que estos errores son inevitables, pero eso no es excusa para no saber manejarlos. Un estudio reciente concluyó que el 18% de las personas que ven una página de error 404 cree que se trata de un error debido a que el sitio está mal hecho. ¿Volverías a un sitio que consideras mal hecho si tuvieras una alternativa?
Es muy importante saber qué poner en una página de error, cómo tratar al visitante e intentar retenerlo, y cómo configurar el servidor para que muestre la página que uno quiere que se muestre, en vez de la fea página por defecto.
Hace poco se hizo un artículo sobre el tema en MaestrosdelWeb. En este artículo se mencionan algunas instrucciones a tener en cuenta para crear una página de error que sirva a los intereses del sitio. Es decir, ya que el error se produce y no lo podemos evitar, debemos intentar que la página de error sea útil al visitante que se la encuentra.
Pero el error 404 no es el único que existe (de hecho, en la mayoría de los casos y según la norma HTTP, debería usarse 410 y no 404) Hay otros errores comunes que pueden darse en casos de restricciones de páginas (403 Forbidden) o errores del servidor (500 Internal Server Error).
La forma más sencilla en servidores Apache (la mayoría) es editar el archivo .htaccess ([punto]htaccess) de la raíz del sitio.
Este archivo puede ubicarse en cualquier carpeta, pero hay que tener en cuenta que las directivas que contenga solo se aplicarán a la carpeta que lo contiene, y a sus subcarpetas. Por lo tanto, si se cambian las páginas de error en un archivo .htaccess ubicado dentro de una carpeta cualquiera, solamente se estarán redirigiendo los errores que ocurran en archivos dentro de esa carpeta.
La forma de especificar una página “personalizada” para los errores es la siguiente:
ErrorDocument [código de error] [ruta absoluta a la página que se quiere usar]
Por ejemplo,
ErrorDocument 404 /error404.htmlErrorDocument 500 /error500.html
Puede usarse la misma página para todos los errores, aunque es recomendable especificar lo que sucedió: no es lo mismo un error temporal (la base de datos no está disponible, por ejemplo), que un error permanente como el 404. También es importante crear y lanzar errores que correspondan con el error real: un problema al conectar con la base de datos no provocará por si mismo un error 500 (“Error interno del servidor”) pero si encontramos y detectamos un problema como este, mostrar una página de error 500 puede ser lo apropiado, después de todo sí se produjo un error “interno”.
A la hora de personalizar las páginas de error no solo se pueden usar
documentos estáticos, sino que se puede usar también un programa PHP (o
en el lenguaje que sea).
El servidor Apache pone a disposición de este programa las variables
$\_SERVER['REDIRECT\_URI']
y $\_SERVER['REDIRECT\_STATUS']
, que indican
respectivamente la ruta que se envió y que causó el error, y el código
del error que se produjo.
Por ejemplo, para generar el famoso
Error 404: No se pudo encontrar el archivo XXX en este sitio
Se podría hacer lo siguiente con PHP:
<?php
echo 'Error '.$_SERVER['REDIRECT_STATUS'].':No se pudo encontrar el archivo '.$_SERVER['REDIRECT_URI'].' en este sitio';
Según la documentación de Apache, también debe enviarse desde la página PHP al navegador una cabecera HTTP indicando el error, para asegurar que el navegador “se entere” de lo que realmente sucedió. Esto también se menciona en la página del manual de header(), que es la función de PHP que realiza el trabajo de enviar cabeceras HTTP al navegador.
Hay que tener en cuenta un detalle más: PHP puede funcionar en el servidor como módulo de Apache o como CGI. La información de cómo está funcionando PHP puede obtenerse ejecutando la función phpinfo(), y viendo la salida de “Server API“. Si pone “CGI“, PHP está funcionando como CGI, mientras que si pone “Apache Handler“, PHP está funcionando como módulo de Apache.
Debido a un pequeño fallo de PHP, estas 2 formas de funcionamiento tienen comportamientos ligeramente diferentes. En el caso de que PHP funcione como CGI, la cabecera a enviar es:
<?php
header( 'Status: 404 Not Found' );
mientras que si es módulo:
<?php
header( 'HTTP/1.0 404 Not Found' );
Como se ve, la diferencia está en que una versión usa Status:
mientras que la otra usa HTTP/1.0
(o HTTP/1.1
, con algunas
diferencias).
Esta diferencia no solamente se da con el error 404, sino también con el
resto de los errores HTTP.
La función header
tiene 2 parámetros opcionales, que pueden servir
para evitar las diferencias de funcionamiento entre las versiones de
PHP.
Según el manual oficial, la sintaxis de la función es
void header ( string $string [, bool $replace [, int $http_response_code ]] )
El primer parámetro, $string
, es el que usamos siempre: una cadena con
el contenido de la cabecera.
El segundo, $replace
, indica si la cabecera enviada con header()
debe
sustituir a otra cabecera previa con el mismo nombre.
Y el tercero e interesante, $http\_response\_code
, indica el código
de respuesta HTTP que estará asociado a la cabecera enviada.
Por lo que, según pude leer en las notas de usuario del manual de PHP,
en vez de usar header
como siempre, se puede evitar el problema de
saber cómo se ejecuta PHP usando simplemente:
<?php
header(' ', true, 404);
Según la persona que escribió la nota, el primer parámetro de la función no debe ser una cadena vacía, de ahí el uso de un espacio. Y en mis pruebas, esto genera una cabecera de error perfectamente válida.
Vale la pena leer las notas del manual de PHP, muchas veces se encuentran cosas muy interesantes. Y vale la pena también pensar un poco fuera de lo normal para encontrar soluciones prácticas a los problemas de todos los días.
Activa Javascript para para cargar los comentarios, basados en DISQUS
El Blog de ElCodiguero funciona sobre Pelican