Barátságos hibaüzenetek - 404

Böngészés során számtalanszor akad az ember hibaüzenetekbe, ezek közül is a leggyakoribb talán az "Error 404: File not found.". Jelentése pedig az "igen, egyszer volt itt egy oldal, de már nincs"-től kezdve az "ezt valaki elgépelte"-ig terjed. A legrosszabb megoldás, ha webfejlesztőként nem törődünk e jelenséggel, és hagyjuk, hogy a webszerver tegye amire képes. A hiba oldal megtervezése is fontos egy site építése során és nem is mindig olyan egyszerű eldönteni, hogy mit tartalmazzon.
A felsorolásból a klienshez köthető hibák jelzéséhez érdemes dinamikus hibalapot készíteni. A szerverhez köthetőeknél inkább egyszerű HTML lapot javasolnék, hogy ne terhelje tovább a gépet és programhiba esetén is megjeleníthető legyen. A továbbiakban a 4xx hibák esetén megjelenítendő információs oldalakkal, ezen belül is a leggyakoribb 404-es lapjával foglalkozunk.
A kulcsszavas keresés szép gesztus a hibaoldalon, hiszen tetszőleges kifejezésre kilistázza a honlap témába vágó oldalait. Ezt érdemes saját kereső programmal vagy a nagyobb keresők sitesearch szolgáltatásával megoldani. Ha nem regisztráljuk az oldalunkat ilyen szolgáltatáshoz, akkor választhatunk a rendelkezésre álló programokból, mint pl. ht://Dig, vagy mi magunk is barkácsolhatunk a meglévő eszközökből, pl. grep. A dinamikus weblapok esetén a keresés nagyobb odafigyelést igényel, nehogy a kódjainkat is megmutassuk a látogatónak.
A visszafogott grafika erősen ízlés dolga, hiszen a robotok úgysem töltik le a képeket. Érdemes úgy megtervezzük a hibalapot, hogy ízléses legyen, de mértékkel, pl. Flash reklámok nélkül. Az is derüljön ki egyértelműen, hogy azért ezt látja a látogató, mert valami hiba történt, ez nem a keresett tartalom.
Az oldal összeállítására Ian Lloyd JavaScript megoldást javasol. Ezáltal a sajátFontos, hogy a HTTP/1.0 (RFC 1945 10.11 pontja) szerint az átirányításban a teljes URL-t illik feltüntetni. Tapasztalataim szerint a relatív URL-eket is lekezelik a böngészők, de alkalmazásuk esetleg nem várt eredményhez vezethet. Működéséhez természetesen be kell állítani a webszerveren is ezt a kódot hibakezelőnek:
A látottak közül nekem a Sun Microsystems hibaüzenete volt a legszimpatikusabb. A hibát úgy erőszakoltam ki belőle, hogy a nemlétező http://hu.sun.com/noezbiztosnincs címet írtam a böngészőbe. A kapott oldal számomra azért tetszetős megoldás, mert:
Hasonlóan pozitív példaként hozhatom fel a Weblabor hibalapját is. Itt a tartalomkezelő rendszer egyik oldalát mutatja meg a webszerver, így a dinamikus részben láthatóak a honlap újdonságai (friss blogmarkok, aktív és új fórumtémák).A fenti megoldással a webmester automatikusan kap egy levelet minden hiba esetén. Néhány hét (perc) után az is kiderül, ha elfelejtettünk '
Az elektronikus levélben történő értesítések hátránya, hogy egy rosszul beállított robot vagy egy aktív hacker gyorsan megtömheti a webmester postaládáját. Ennek elkerülésére célszerű saját logfájlt vagy adatbázist használni. Adatbázis esetén induljunk ki valami hasonló szerkezetből (SQLite példa):Az elkészített tábla 'A fenti példa ADOdb felhasználásával könnyen átvihető tetszőleges szerverre és adatbázisra. Az SQL utasítás összeállításában a szöveges adatok levágása a
A fenti példával tetszőleges átirányítás megoldható egyszerű regulás kifejezések alkalmazásával, akár másik szerverre is. Átköltözés esetén az Apache dokumentáció a következő mintát javasolja:Amely leellenőrzi, hogy létezik-e a fájl és ha nem, a kérést átküldi webserverB.com-ra. Ez a megoldás természetesen csak a Sajnos a használata többletmunkát igényel a szervertől, ezért a teljesítmény megtartása érdekében általában a szkriptekre bízzák az átirányítást is. További hátránya, hogy a site-on belüli átirányítás esetén a látogató a régi URL-t is valódinak és érvényesnek látja. Ezt a problémát már csak programozással oldhatjuk meg. A látogatót a megfelelő fejléc elküldésével értesíthetjük arról, hogy ezentúl új címet keressen:
A 301 és 302 kódok közötti különbség, hogy a 302 esetében később a tartalom ismét megtalálható lesz az adott URL-n, de a 301 esetében már nem. A 301-es kódot látva a keresőrobotok lecserélik a tartalomhoz vezető URL-t az új címre.
Érdemes tehát esetleg a hibakezelést kombinálni egy átirányítás ellenőrzéssel is. Ekkor figyelni kell arra, hogy az elküldött header információ megelőzzön minden más kiírt szöveget. Sikeres átirányítás során a státusz kód és az új cím megadása után lépjünk is ki a programból. Mivel aEnnek a karbantartása a webmester feladata, a programba illesztése pedig egyszerű (A fenti program dekódolja a kérés címét, majd megkeresi az esetlegesen hozzá kapcsolódó átirányítást. Érvényes XHTML generálásakor ugyan problémás az URL paramétereket elválasztó '
■ Hibaüzenetek és kódok
A hibaüzeneteket és kódjaikat (legalábbis egy részüket) az alábbi táblázat foglalja össze. A kódok a szerver által adott válasz fejlécében "HTTP/x.y KÓD" kapnak helyet (az RFC 1945 6.1 pontja definiálja ezt a kérdést, egy részletesebb listát pedig az RFC2616-ban olvashatunk). A szerveren futó programokkal - indokolt esetben - befolyásolhatjuk, hogy mi kerüljön ide, például így működik a phpMyAdmin 'http' beléptetési módja is. Figyeljük meg, hogy a kód első száma (a százas helyiértéken levő) a kód típusát definiálja, a négyessel kezdődő (4xx) a kliens, míg az ötössel kezdődő (5xx) a szerver oldalon keletkező hibákat jelöli:| Kód | Jelentése |
|---|---|
| 400 | Bad Request - rosszul formázott kérés |
| 401 | Unauthorized - a felhasználó még nem azonosította magát |
| 403 | Forbidden - a kért anyaghoz nincs hozzáférési joga |
| 404 | Not Found - a kért anyag nem található |
| 500 | Internal Server Error - váratlan programhiba történt |
| 501 | Not Implemented - a keresett funkció nem elérhető |
| 502 | Bad Gateway - a gateway/proxy hibás adatokat kapott |
| 503 | Service Unavailable - a szerver túlterhelt, vagy karbantartás miatt nem elérhető |
A felsorolásból a klienshez köthető hibák jelzéséhez érdemes dinamikus hibalapot készíteni. A szerverhez köthetőeknél inkább egyszerű HTML lapot javasolnék, hogy ne terhelje tovább a gépet és programhiba esetén is megjeleníthető legyen. A továbbiakban a 4xx hibák esetén megjelenítendő információs oldalakkal, ezen belül is a leggyakoribb 404-es lapjával foglalkozunk.
Funkciók
Ian Lloyd a "The Perfect 404" cikkében azt javasolja, hogy az oldal tartalmazzon:- Navigációs elemeket, legalább egy linket a címlapra vagy honlaptérképre
- Kulcsszavas keresési lehetőséget
- Visszafogott grafikát
A kulcsszavas keresés szép gesztus a hibaoldalon, hiszen tetszőleges kifejezésre kilistázza a honlap témába vágó oldalait. Ezt érdemes saját kereső programmal vagy a nagyobb keresők sitesearch szolgáltatásával megoldani. Ha nem regisztráljuk az oldalunkat ilyen szolgáltatáshoz, akkor választhatunk a rendelkezésre álló programokból, mint pl. ht://Dig, vagy mi magunk is barkácsolhatunk a meglévő eszközökből, pl. grep. A dinamikus weblapok esetén a keresés nagyobb odafigyelést igényel, nehogy a kódjainkat is megmutassuk a látogatónak.
A visszafogott grafika erősen ízlés dolga, hiszen a robotok úgysem töltik le a képeket. Érdemes úgy megtervezzük a hibalapot, hogy ízléses legyen, de mértékkel, pl. Flash reklámok nélkül. Az is derüljön ki egyértelműen, hogy azért ezt látja a látogató, mert valami hiba történt, ez nem a keresett tartalom.
Az oldal összeállítására Ian Lloyd JavaScript megoldást javasol. Ezáltal a saját
404.html hibakezelő lapunk dinamikussá válhat és kiválasztott paraméterek alapján összeszerkeszthető a tartalma. Ha pedig a böngészőben a látogató letiltotta a JavaScript támogatást, egy statikus lapot kap (<noscript> tagon belüli rész). Ezt én annyiban egészíteném ki, hogy szerintem szerver oldalon érdemes összeállítani egy ilyen dinamikus lapot és akkor teljesen mindegy, hogy van-e JavaScript támogatás, vagy sem. További előnye, hogy a szerver oldalon hozzáférhetünk adatbázisokhoz, a tartalomkezelőhöz stb.Minta megoldások
Több nagyobb cég honlapját meglátogatva kipróbáltam, hogy mit is gondolnak az ottani programozók a 404 hibaüzenet megjelenítéséről. Érdekes, hogy sokan választották az egyszerű átirányítást, tehát a látogató hiba esetén a címlapra érkezik. PHP-ban ez valahogy így néz ki (legyen a neve "elso404.php"):<?php header('Location: http://www.mysite.com/'); ?>- Apache esetén a .htaccess fájlba vagy a <VirtualHost> beállításainál megadni:
ErrorDocument 404 /elso404.php - Microsoft IIS szerveren az IIS Manager-ben állítható át (help: "About Custom Error Messages").
A látottak közül nekem a Sun Microsystems hibaüzenete volt a legszimpatikusabb. A hibát úgy erőszakoltam ki belőle, hogy a nemlétező http://hu.sun.com/noezbiztosnincs címet írtam a böngészőbe. A kapott oldal számomra azért tetszetős megoldás, mert:
- A cégre jellemző navigációs panel látható a lap tetején.
- A Sun és a technikai központ elérhetősége kiemelt dobozokba került a bal oldalon.
- A dinamikus tartalomban feltünteti a legutóbb létrehozott és változott URL-ek listáját.
Hasonlóan pozitív példaként hozhatom fel a Weblabor hibalapját is. Itt a tartalomkezelő rendszer egyik oldalát mutatja meg a webszerver, így a dinamikus részben láthatóak a honlap újdonságai (friss blogmarkok, aktív és új fórumtémák).
Haladó megoldás
Webmester értesítése
Azon kívül, hogy webmesterként időnként átbogarásszuk a szerver logokat, egyéb lehetőségek is vannak. Ha már rászánjuk az időt és dinamikus hibalapot készítünk, legyen része az automatikus visszajelzés is (masodik404.php):<?php
//... levél a webmesternek ...
$mailbody = 'Request: '. $_SERVER['REQUEST_URI'] ."\n";
$mailbody .= 'Referer: '. $_SERVER['HTTP_REFERER'] ."\n";
$mailbody .= 'User: '. $_SERVER['REMOTE_ADDR'] .' : ';
$mailbody .= $_SERVER['HTTP_USER_AGENT'] ."\n";
mail('webmaster##kukac##mysite.com','404 Error report',$mailbody);
//... a dinamikus tartalom kódja ...
?>
favicon.ico' vagy 'robots.txt' állományokat elhelyezni tárhelyünkön. A HTTP_REFERER segítségével kideríthetőek a szerkesztési hibák (a hivatkozó oldalra rosszul helyeztünk el egy linket), a HTTP_USER_AGENT segítségével (elvileg) eldönthetjük, hogy egy robot kéri-e a lapot, vagy egy ember ül a gépe előtt és böngészget. Ez utóbbi feltétel felhasználható a dinamikus tartalom felépítésében is. A webmesternek küldött levél pedig kiegészíthető egyéb információkkal is, akár a $_SESSION és a $_COOKIE tömbök tartalmával is.Az elektronikus levélben történő értesítések hátránya, hogy egy rosszul beállított robot vagy egy aktív hacker gyorsan megtömheti a webmester postaládáját. Ennek elkerülésére célszerű saját logfájlt vagy adatbázist használni. Adatbázis esetén induljunk ki valami hasonló szerkezetből (SQLite példa):
CREATE TABLE errorlog (
ido INTEGER,
hibakod INTEGER,
ip VARCHAR(40),
request VARCHAR(250),
referer VARCHAR(250),
user VARCHAR(250)
);ido' eleme tartalmazza a dátumot Unix timestamp formátumban. Feltöltésére az e-mail küldés helyett a következő kódot használhatjuk (harmadik404.php):<?php
//... adatbázis feltöltés ...
include 'adodb/adodb.inc.php';
$errorDB = &ADONewConnection('sqlite');
$errorDB->PConnect('pathto/logfile.db');
$bind = array();
$bind[0] = intval(date('U'));
$bind[1] = isset($_SERVER['REMOTE_ADDR']) ? substr($_SERVER['REMOTE_ADDR'],0,40) : 'n/a';
$bind[2] = isset($_SERVER['REQUEST_URI']) ? substr($_SERVER['REQUEST_URI'],0,250) : 'n/a';
$bind[3] = isset($_SERVER['HTTP_REFERER']) ? substr($_SERVER['HTTP_REFERER'],0,250) : 'n/a';
$bind[4] = isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'],0,250) : 'n/a';
$Query = "INSERT INTO errorlog VALUES(?, 404, ?, ?, ?, ?)";
$ok = $errorDB->Execute($Query, $bind);
//... a dinamikus tartalom kódja ...
?>substr függvénnyel akkor hasznos, ha valaki megpróbálja túlterhelni programjaink bufferét. A webmester értesítését pedig bízzuk inkább naponta automatikusan (pl. crontab) lefuttatott önálló programra. A site adminisztrációs felületén pedig napló nézegető és elemző menüket helyezhetünk el:- Az utóbbi N nap bejegyzései (a határidő számítása PHP-ben : date('U') - $nap*24*3600):
SELECT * FROM errorlog WHERE ido>={hatarido} ORDER BY ido DESC; - Legaktívabb IP címek Top10 listája:
SELECT ip,count(*) as darab FROM errorlog GROUP BY ip ORDER BY darab DESC LIMIT 10;
Mit is keresett...
Különösen nagyobb oldalakon előfordul a tartalmak átszerkesztése, URL-ek eltűnése, átnevezése. Ez zavarba hozza a látogatót és a kereső robotokat is. A zökkenőmentes átállás segítésére megpróbálkozhatunk egy "gondolatolvasó" trükkel. A webszervereken beállítható, hogy a beérkező kérést átfogalmazza. Apache esetén ezt amod_rewrite modul végzi el. Használata a httpd.conf vagy .htaccess fájlokban a következő:
RewriteEngine on
RewriteRule ^/regiurl(.*) /athelyezett$1
RewriteEngine on
RewriteCond /your/docroot/%{REQUEST_FILENAME} !-f
RewriteRule ^(.+) http://webserverB/$1
DocumentRoot-on belüli fájlokra használható. A feltétel kicserélhető, és ekkor minden URL-t lekezel:
RewriteCond %{REQUEST_URI} !-U
| Kód | Jelentése |
|---|---|
| 300 | Multiple - több helyre is költözhetett (jelenleg nem támogatott a böngészőkben) |
| 301 | Moved Permanently - véglegesen áthelyezve |
| 302 | Moved Temporarily - pillanatnyilag ideiglenesen áthelyezve |
| 304 | Not Modified - a tartalom nem változott (válasz feltételes kérésre) |
A 301 és 302 kódok közötti különbség, hogy a 302 esetében később a tartalom ismét megtalálható lesz az adott URL-n, de a 301 esetében már nem. A 301-es kódot látva a keresőrobotok lecserélik a tartalomhoz vezető URL-t az új címre.
Érdemes tehát esetleg a hibakezelést kombinálni egy átirányítás ellenőrzéssel is. Ekkor figyelni kell arra, hogy az elküldött header információ megelőzzön minden más kiírt szöveget. Sikeres átirányítás során a státusz kód és az új cím megadása után lépjünk is ki a programból. Mivel a
REQUEST_URI változó tartalmazza a kérést, célszerű az előbbi adatbázist kiegészíteni egy átirányítás táblával, amiben kereshetünk:
CREATE TABLE redirect (
id INTEGER,
regicim VARCHAR(250),
ujcim VARCHAR(250)
);
negyedik404.php):<?php
//... adatbázis feltöltés ...
//... átirányítás, ha lehetséges ...
$kerdes = strtolower(substr(urldecode($_SERVER['REQUEST_URI']),0,250));
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
$Query = "SELECT * FROM redirect WHERE regicim = ? LIMIT 1;";
$row = $errorDB->GetAssoc($Query, array($kerdes));
if (isset($row['ujcim'])) {
header($protocol .' 301 Moved Permanently');
header('Location: '. urlencode($row['ujcim']));
exit;
}
//... a dinamikus tartalom kódja ...
?>&' jel, amelyet ott '&' formában illik átadni, a header függvény használatakor az eredeti '&' jelet kell alkalmazni.Összegzés
A hibalapok közül leggyakrabban a 404-esekkel találkozunk böngészés során. A 404-es hibalapoknak a feladata az eltévedt szörfözők és robotok útba igazítása. A statikus "File not found" szöveg helyett ma már elvárható, hogy a honlapunk navigációs elemei, keresés és dinamikus útbaigazító tartalom jelenjenek meg. Ezeken felül a hibakezelő szkript automatikus értesítő levelet küldhet a webmesternek vagy adatbázisban tárolhatja az eseményeket, a kérés elemzésével pedig megtalálhatja a keresett tartalom új helyét és oda átirányíthatja a látogatót. A honlap programozójának ilyen pár soros apró figyelmességei bőven megtérülnek a site fenntartása és esetleges későbbi átalakítása során.





angol v. magyar
angol v. magyar
Linkek
Creating Custom Error Messages in Apache
adoDB Execute
Az utóbbit azért mert a cikkben kicsit 'piszkos' módon használod.
execute javítva
html entity?
Ez tévedés, ezt a bizonyos '&' jelet csak (x)html kódban illik '&' (ld. html entities) formában írni, a header függvény esetében nem kell a html entity, elég maga a '&' jel (mint ahogy a böngésződ címsorába sem http://www.szerver.hu/index.php?p=x&q=y formában írod az url-t)
----
Az első példaszkript (elso404.php) nem tökéletes ebben a formájában:
Első script
-boogie-
html entity?
eredménye:
Array
(
[a] => 1
[amp;b] => 2
)
Gyulus
nem feltétlen
ez alapértelmezésben csak az és-jel (&)
valahol azt ajánlották, hogyha érvényes (X)HTML oldalakat generál az ember, akkor érdemes a pontosvesszőt (;) is belevenni a felsorolásba; így a HTML elemeket nem értő böngészők és internet explorerek kéréseit ki lehet szolgálni helyesen:
GET /index.php?valtozo1=ertek1&valtozo2=ertek2 HTTP/1.0ekkor a
$_GET/$_REQUESTváltozókban lesz három tömb-elemvaltozo1,#38ésvaltozo2kulcsokkal.bbalint
igazatok van
503
http://alo.antville.org/
:-))
Elköltözött oldal
Új címen
Attila
Micsoda ötlet!
URL paraméter
<Nincs cím>
Kérés: http://regicim/oldal.html
Válasz: HTTP 301, ide irányítva: http://ujcim/regi-cimrol-jon/http://regicim/oldal.html
Kérés: http://ujcim/regi-cimrol-jon/http://regicim/oldal.html
Válasz: HTTP 301, ide irányítva: http://ujcim/oldal.html + session adat beállítás, hogy régi címről érkezett
Kérés: http://ujcim/oldal.html
Válasz: HTTP 200, taratlom + figyelmeztetés ha régi címről érkezett
Attila
Szerintem...
http://regicim/index.php?p=view&id=4
ebből a rquest_uri-ból megkapom a "index.php?p=view&id=4" stringet
és átirányítom a kérést a
http://ujcim/index.php?p=view&id=4®i=true
és ha regi == true, akkor kiírom a szöveget, hogy új az oldal, meg 200-as státusz.
Ez így milyen
<Nincs cím>
Attila
<Nincs cím>
Ezt nem Rewrite-al kéne megcsinálni?
mert az új tárhelyemen IIS van.
<Nincs cím>
http://ujcim/redir.php?oldUri=http://regicim/index.php?p=view&id=4
De az oldUri paraméter értékét (ebben az esetben is) először át kell kódolni, PHP-ban rawurlencode(), ha minden igaz, bár ez ennél a cikknél már teljesen off.
Attila
<Nincs cím>
Az is megoldás, hogy a regi mappába is lehelyezek egy index.php-t, ami átirányítja az usert a http://ujcim/index.php?p=view&id=2 -re.
Amúgy ebben a sorrendben kell csinálni az átirányítást: Igaz?
1. az user megnézi a régi oldalt
2. kiadom a 301-es státuszt
3. átirányítom az usert az új címre
4. az új címen kiadok egy 200-as státuszt (vagy ez nem is kell?)
5. átirányatom a végleges címre.
<Nincs cím>
index.php lényegi része kb:
index.php lényegi része kb:
index.php lényegi része kb:
<Nincs cím>
Ki van adva
Attila
<Nincs cím>
Bérelt tárhelyen hogyan tudok ...
A kérdés tehát hogyan tudom a bérelt tárhelyemen létre hozni hogy meg kapjam a referer-t.
A .htaccess lehetséges beleírtam az első példát, és megírtam a másodikat. De így az URI az az elso.php tehát nem az igazi 404 kérés.
A másik kérdés a 301 kiadása egy megszüntetet oldalnál. (olvasom, de nem értem sajna) Van php nysql meg .htaccess csak magához szerverhez nem férek hozza ugye bár.
K.K.
Szerver tulaj?
A 301 kiadása csak akkor lehetséges, ha a régi szerverhez, régi domain névhez is hozzáférsz. Nyilvánvalóan nem lehetséges, ha nem.
-boogie-
Köszi de ..
Ha jól olvastam a cikket akkor ehhez nem feltétlen kell server admin.
Ami ugyan megoldható hogy írok egy mail-t de én szeretném át állítani az oldalt html-ről php-re. De a régi oldalak hivatkozásait se akarom elveszteni. A keresők meg sajna nagyon lassan felejtenek. :-(
Ezért az adatbázisos - 301 - átirányításig szeretnék eljutni.
Köszi.
K.K.
Nem de...
.htaccesshasználatát, nem mindenhol engedélyeznek egyes beállításokat állítani.htaccess-ből.-boogie-
Re: tárhely szolgáltatón
Üdv.: BarLac
Igen megtettem létre tudok hozni nincs letiltva.
*szerk Jajj látom az URI az jogos, de ugye sokszor nem jön referer. :-(
Igen megtettem egy .htaccess a gyökérbe.
ErrorDocument 404 /elso404.php tartalommal.
A z elso404.php-ba meg a
Mit csinálok rosszul.
K.K.
<Nincs cím>
Akkor ott valami nem stimmel. Nem lehet, hogy van egy RewriteRule, ami nem létező kérés esetén az "elso404.php"-t adja vissza? Egy
Üdv.: BarLac
Szerintem nincs semmi baj a szerverrel, én vagyok buta.
Nem ReWrite van, én tettem a szolgáltató által adott mappámba (gyökér)
Egy ErrorDucoment ... tartalmú htaccess fájlt.
Mert én így értettem a példát.
Télleg nem tudom hogy kéne.
A htaccess-be írhatok php-t?
Vagy nem tudom.....
K.K.
Írhatsz
ErrorDocument 404 http://www.kiszolgalo.com/error/index.php?error=404
Amúgy meg:
http://httpd.apache.org/docs/1.3/misc/custom_errordocs.html
Sok sikert hozzá!
Mintha haladnák.
Az elöbbi kódodban még jó az URI. Közdük még vele, nem tudnám lemásolni a masodik.php-t. :-(
K.K.
ez se rossz...
Ez nagyon barátságos: