Ověření unikátnosti uživatelského jména u klienta

Školení, která pořádám

Při vyplňování formuláře uživatelé ocení, když jim už na straně klienta oznámíme, že něco vyplnili špatně. Data se tak nemusí přenášet neustále tam a zpět a práce je mnohem plynulejší. U obvyklých kontrol neprázdnosti nebo vyhovování masce to jde poměrně snadno, u ověření existence uživatelského jména (nebo obecně jakéhokoliv údaje, který musí být jednoznačný) je potřeba dát pozor i při ověření na straně serveru. Jak se to dá řešit na straně klienta?

Nápad přenášet ke klientovi všechna existující uživatelská jména není zrovna nejšťastnější, protože se může jednat o citlivé údaje. Při přenášení hashů jmen prozradíme přinejmenším jejich počet, navíc při velkém množství těchto údajů je jejich přenášení zbytečně zdlouhavé.

Zjišťovat existenci daného uživatelského jména tedy bude lepší až poté, co ho uživatel vyplní. Jedna možnost je použít AJAX, ten mi ale přijde jako zbytečně silná zbraň. Druhou možností je dynamicky načítat JavaScript s kódem, který ověření provede:

<script type="text/javascript">
function check(s) {
	var checker = document.createElement('script');
	checker.src = 'login_exists.php?login=' + encodeURI(s);
	document.getElementById('regform').appendChild(checker);
	return false;
}
</script>
<form id="regform" action="" method="post" onsubmit="return check(this['login'].value);">
Login: <input name="login" />
<input type="submit" value="OK" />
</form>

Skript login_exists.php potom může vypadat takhle:

<?php
header("Content-Type: text/javascript");
if (mysql_result(mysql_query("SELECT COUNT(*) FROM uzivatele WHERE login = '" . mysql_real_escape_string($_GET["login"]) . "'"), 0)) {
    echo "alert('Zadaný login již existuje.');\n";
} else {
    echo "document.forms['regform'].submit();\n";
}
?>

Funkce check() zahájí načítání skriptu a oznámí prohlížeči, ať formulář zatím neodesílá. O to se případně postará až kód vygenerovaný skriptem login_exists.php. Pokud ale zadaný login už existuje, zobrazí se uživateli informace. Bez JavaScriptu se formulář odešle standardně.

Připomínám, že takováto kontrola může sloužit pouze pro zlepšení uživatelova dojmu, kontrola na serveru zůstává nepostradatelná.

Přijďte si o tomto tématu popovídat na školení JavaScript a AJAX.

Jakub Vrána, Řešení problému, 23.12.2005, diskuse: 14 (nové: 0)

Diskuse

Leo:

Akorat bych pri dalsim pokusu neapendoval, ale replacechildoval :-) Leo

tark:

vypadá to dobře!

karel:

nevím, proč by měl být Ajax silná zbraň? Kód by byl zhruba stejně dlouhý a neděla by se tam taková věc, jako je přidávání javascriptu do DOM...

Jakub:

Souhlasim s karlem. AJAX je pro tohle jako stvoreny. Zajimalo by me, kde bys ho chtel pouzivat kdyz ne u vyhravcicek v UI jako je tahle...

Oswald:

Myslím, že způsob přes dynamický vytvořený script je pro takouvouhle mini-aplikaci nejjednoduší. Zrovna mynulý týden jsem tohle řešil a udělal to přes Ajax (http://cal.webkitchen.cz/reg.php). Ještě poznámka: funkce encodeUri je na kompletní URL, na vytváření query stringu je vhodnější encodeURIComponent.

Leo:

Ajax ma jednu podstatnou vadu - v IE neni defacto realizovany JavaScriptem ale ActiveXem, bez nej si tam ani neu... vsak vite co. DOM reseni je mnohem cistsi, na takovyhle jednoduchy veci, kde nepotrebuju treba POST nebo modifikovat ci cist HTTP hlavicky. Leo

Oswald:

Tak ten minulý komentář se mi - z češtinářského hlediska - opravdu povedl :-)

Ondra:

Rad bych pripomel, ze i toto reseni je AJAX. Ac si mnozi mysli, ze AJAX === XmlHTTPRequest, neni tomu tak - AJAX je souhrnny nazev pro princip/technologii, jez je zde evidentne vyuzivana. Nebot cely proces overovani formularoveho prvku je tezce asynchronni a realizovan JavaScriptem :)

ikona Jakub Vrána OpenID:

AJAX = Asynchronous JavaScript and XML. Takže tohle není AJAX, protože XML použito není.

ikona llook:

Názory na definici AJAXu se různí. Moje soukromá definice je zhruba "prvky RIA, realizované pomocí základních vlastností webového prohlížeče". Já bych to za AJAX považoval.

Obecně pokud použiju "část technologie", říkám že používám "technologii".

Leo:

A ja tomu vsemu rikam komunikace klient-server JavaScriptem na pozadi stranky. Nabubrele skatulky jako RIA nemam rad (stejnojmenna cokoladka ovsem kdysi sla :-) Leo

ikona spaze:

RIA je něco jinýho než čikuládka ne? :P
http://www.hartmann.cz/obsah/?damska_hygiena

Jinak RIA = Rich Internet Application, tak jest?

roman:

ahojte, zkousel jsem vlozit uvedeny sample do meho kodu, ale ie hlasi chybu jscriptu na line 2 char 1 - syntax error.
kdyz zmenim hodnotu v zavorce 'function check(s)' na prazdne misto nebo neco jineho napr. user, protoze tak se jmenuje moje pole tak se zadna chyba nevygeneruje, nicmene script nefunguje.

pls help

jaja:

Chybu mas nekde v tom login_exists.php zkus si jej odladit samostatne. Pak to chodi.

Vložit příspěvek

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2016 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.