Iš tiesų pirmąjį scenarijų parašiau ne aš, o IdeaG, tačiau aš nusprendžiau tęsti jo pradėtą darbą. Taigi ką naujo sužinosite šiandien? Šį kartą norėčiau pristatyti POST metodą ir darbą su formomis.

Tarkim jūs turite registracijos formoje patikrinti ar toks vartotojo vardas yra laisvas. Čia aš nekalbėsiu apie visą registraciją, tiesiog pateiksių skriptą, kuris patikrins ar norimas slapyvardis užimtas ir paaiškinsiu kaip jį realizuoti.
Prieš skaitant toliau, primygtinai siūlau perskaityti “pirmąjį Ajax scenarijų”.

Pasiruošę? Tai pradėkime.

Aš neįsivaizduoju registracijos be duomenų bazės. Čia pateiksiu paprastą modelį, kurį naudojau šiame scenarijuje, be abejonės, jums reikės žymiai sudėtingesnio.

CREATE TABLE `list` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(250) UNIQUE DEFAULT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Taigi turime lentelę, kurioje saugomi slapyvardžiai. Dabar apsirašysime PHP skriptą, kuris atliks juodą darbą, t.y. patikrins ar nėra užimtas slapyvardis, jeigu laisvas - užregistruos. Tas failas pas mane vadinasi check.php

//- čia turi būti jusų prisijungimas prie duomenų bazės
if (get_magic_quotes_gpc()) {      
if(ini_get('magic_quotes_sybase')) {
                $var        = str_replace("''", "'", $_POST['act']);
            } else {
                $var       = stripslashes($_POST['act']);
            }
} else {
$var = $_POST["act"];
}
$var = mysql_real_escape_string($var);
$result = mysql_query("SELECT * FROM list where name='$var'");
$number=mysql_num_rows($result);
if($number>0) {
echo("Uzimta");
} else { 
$result = mysql_query("INSERT INTO list (name) VALUES ('$var')");
echo("Ivesta");
}

http://pixel.paste.lt/paste/4646cb13751af27681009f6d22e06e1e

Šio kodo logika labai paprasta, jeigu galim paimti duomenis su norimu slapyvardžiu, vadinasi jis užimtas, jeigu ne, tuomet reikia jį užregistruoti. Tai tiek su paprasta dalimi, dabar pereikime prie linksmosios - .

function createRequestObject() { 
   var req; 
   if(window.XMLHttpRequest){ 
      // Firefox, Safari, Opera... 
      req = new XMLHttpRequest(); 
   } else if(window.ActiveXObject) { 
      // Internet Explorer 5+ 
      req = new ActiveXObject("Microsoft.XMLHTTP"); 
   } else { 
      // TJeigu naršyklė yra sena ir nepalaiko Ajax
      alert('Problem creating the XMLHttpRequest object'); 
   } 
   return req; 
} 
 
//Sukuriamas XMLHttpRequest objektas 
var http = createRequestObject();

Nors ši funkcija atrodo kitaip nei pirmoji pirmajame scenarijuje, tačiau ji atlieka tuos pačius veiksmus - sukuria XMLHttpRequest objektą priklausomai nuo naršyklės tipo.

Dabar įdomiausioji šio straipsnio dalis - funkcija, kuri paima duomenis ir perduoda juos POST metodu PHP skirptui.

function sendRequest(act) { 
   http.abort; 
   http.onreadystatechange = handleResponse;
   http.open('post', 'check.php', true); 
   http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
   http.send('act='+escape(act)); 
}

Kaip matote duomenis ši funkcija gauna per parametrą: jokių apdorojimo veiksmų neatlieka, tiesiog siunčia juos POST metodu.
Kai duomenys perduodami GET metodu nereikia nustatyti antraščių tipo, o send komandai paprasčiausiai paduodama null.

Trečioji funkcija skirta duomenų atvaizdavimui, taip pat iš principo nesiskiria nuo to kas buvo pirmajame Ajax scenarijuje.

function handleResponse() { 
   if(http.readyState == 4 && http.status == 200){ 
      var response = http.responseText; 
      if(response) 
      { 
         //atnaujinamas elemantas kurio id yra ajaxTest  
         document.getElementById('ajaxTest').innerHTML = response; 
      } 
   } 
}

Štai ir visas kodas, dar reikia pridėti HTML, kurį naudojau duomenų paėmimui bei atvaizdavimui, nors tikriausiai patys jau numanote, kaip tas kodas turėtų atrodyti.

<form name="myform" id="myform" >
Vardas <input  type="text" name="nick"  id="nick" />
  <input type="button" name="button" value="Gerai" onClick="javascript:sendRequest(document.myform.nick.value);" /></form>
<hr>
<div id="ajaxTest"></div>

Štai ir visas džiaugsmas. Tačiau prieš baigdamas norėčiau atkreipti jūsų dėmesį dar į dvi eilutes iš parašyto skripto

document.getElementById('ajaxTest')
// vs
document.myform.nick.value

Pirmu atveju prie elemento javascript prieina per id, antruoju - pavadinimą. Abu variantai yra geri ir teisingi, tiesiog žinokit, jog taip įmanoma.

Straipsnį paruošti padėjo:
Simple Introduction to AJAX and XMLHttpRequest

Parsisiuntimui:
Ajax skriptas

Atnaujinimas 2007-07-14 16:56: straipsnis atnaujintas remiantis ‘ZaZa’ ir ‘asterisk’ komentarais, ačiū.
Straipsnio papildymas: “Mano antrasis Ajax scenarijus” remake by Sergej Kurakin

Panašūs straipsniai


“Mano antrasis Ajax scenarijus” komentarų: 18


  1. Iš PHP puses neatsizvelgta (ar nepasakita) į magic_guotes_gpc. Iš SQL puses laukas `name` turi tureti unikalu rakta, ir jai `id` PRIMARY tai UNIQUE jam nereikia. Be to POST parametrus reikia su JS kodoti su tam tikra funkcija (nepamenu tiksliai kuri, bet ne escape)

  2. asterisk

    Na remiantis nustatymais pagal nutylėjimą magiq_quotes_gpc berods yra išjungtas. Tiesiog galbūt reikėjo paminėti kaip elgtis jeigu jis būtų įjungtas.

    Dėl `name`, taip reiktų nustatyti unikalų raktą, tačiau jeigu su PHP patikrinama ar toks vardas neegzistuoja, realiai grėsmės nėra vardų susidvejinimui, nebent duomenys įkeliami tiesiai per sql, šiuo atveju kalba eina apie php.
    Taip, UNIQUE tikrai nereikia.
    O kam POST parametrus koduoti su JS ?

  3. asterisk

    P.s. jeigu kažkas abejojat dėl magic_quotes_gpc, tai vietoj:
    [code lang=”php”]
    $var=mysql_real_escape_string($_POST[”act”]);
    [/code]
    Įdėkit šitą kodą:
    [code lang=”php”]
    if (get_magic_quotes_gpc()) {
    if(ini_get(’magic_quotes_sybase’)) {
    $var = str_replace(”””, “‘”, $_POST[’act’]);
    } else {
    $var = stripslashes($_POST[’act’]);
    }
    } else {
    $var = $_POST[”act”];
    }
    $var = mysql_real_escape_string($var);
    [/code]
    http://pixel.paste.lt/paste/10dd7a9715f0b3fe7b4b73a191cb6fa8


  4. Hm, asterisk, jo, gal ir nereikia, bet sveika butu ideti, kadangi `name` turi buti unikalus riamiantis uzduotimi, todel saugumo sumetimui patariu baze dariti gerai, be to tai mokimo medziaga. As puikiai suprantu, kad esant mazam duomenu kiekiui indeksai gali i stabditi, bet esant dideliam kiekiui jie gelbes.

    Del POST domenu kodavimo: o kas bus jai ivesim “D&G” -jai per atostogas neprageriau smegenu, atrdlius per post tik act=”D” ir G=”", nes gausine POST parametrus: act=D&G o tai jau ne tai ka norime gauti.

    WAP:u sunku rašyti, rytoj busiu Vilniuje apžiuresiu rimčiau.

  5. asterisk

    Hm, taip tu teisus. Bet tam tikrai užtenka escape man atrodo ;)


  6. Suriraskit internete patikima manuala apie JavaScript ir pasidomekite skiptuma tarp funkciju: escape ir encodeURIComponent. Jai as neklistu (ir matau iš DB) mes naudojam UTF-8 ;-)


  7. Pagaliau grižau į Vilnių, kur yra normalus kompiuteris ir internetas (aš neturiu nešiojamojo/skriestuko, kadangi ju nekenčių).

    Pastebesių dar vieną pateikto pavizdžio minusiuką. Jai ponas NePo pateiktu truputi didesnį formos pavizdį, kur be prisijungimo vardo butu nors el. pašto įvedimas ir slaptažodžio įvedimas - visas reikalas butu truputi sudetingesnis.

    Pirmiausia, tada butu taip, kad patikrinimas, ar toks prisijungimo vardas jau yra turetu įvikti, kai žmogus nustojo rinkti prisijungimo vardą. Todėl tektu naudoti “onblur” yvikį, arba “onchange” su žymiai sudetingesnė logiką.
    Reiketu tik paprasčiausiai patikrintų, ar nera tokio vartotojo vardo, ir jai yra, ta įvedimo lauką padaritų raudona, galimas ir pranešimas, kaip yra dabar.

    Antra, per patikrinima nebutu jokių įterpimų - nes tai tik patikrinimas, ar toks vartotojas jau užregistruotas. Duomenų įterpimas įviktu tik kai vartotojas užpilditų visa formą, kitaip patikrinimas sukiš į bazė visus vartotojų vardus ir užregistruoti norimo vardo, teoriškai niekada nepaviks.

    Dar vienas pastebejimas butu tai, kad jai pas vartotojo neveikia JavaScript (atjungtas, nepakrovė .js rinkmenos, įviko kažkodėl klaidą) jis užsiregistruoti Jūsų atveju negalės. Viskas priklauso nuo tinklapio/serviso, bet, patartina AJAXinius dalikelius kabinti taip, kad vis dėlto ir be ju veiktu.


  8. Wow, hebra, geras, nepastebejau dydžiulės ir įdomios klaidos:

    http.open(’post’, ‘check.php’, false);

    Trečio “open” metodo parametro (async) reikšme yra FALSE, vadinasi, tai ne “Asynchronous” o “Synchronous”, ir kol iš serverio nebus gautas atsakimas, naršiklė bus kaip ir pakibusi ir vartotojas negalės testi formu užpildimo.

    Kažkas vėl blogai atliko namų darbus?

    http://www.w3.org/TR/XMLHttpRequest/#dfn-open


  9. “Mano antrasis Ajax scenarijus” remake by Sergej Kurakin - mano manimu tai turėjo buti taip. Galite kritikuoti, kad nebutu į vienus vartus.

    Ne, pixel.lt aš straipsniu nerašisiu.


  10. O tai kur moderatorius ir komentarai? Mire?

  11. asterisk

    ZaZa, truputį susireikšminai ties registracijos forma. Straipsnio esmė manau ne būtent tie laukai egzistuojantys, o pavyzdukas kaip naudotis Ajax ir POST metodu.
    Taip ten tikrai reikia true, nežinau kodėl NePo sugalvojo padaryti false..

  12. asterisk

    ZaZa, nenumirė moderatorius :)
    Tiesa, dėl kritikos - tavo kritika super ;) O prie kodo priekabiauti visada sveika.
    P.s. kur anksčiau rašiau kad turėtų užtekti escape, klydau, jis juk ne visus simbolius escapina.. Kad ir ‘+’ yra palaikomas kaip tarpas.
    Taip pat pilnai sutinku su onchange/onblur pasiūlymu, bet vistiek manau straipsnio idėja buvo parodyti Ajax POST principą, o ne tobulą registracijos skriptą ;)

  13. NeWorld

    jei gerai pamenu turėjau bėdų naudodamas http.abort(), ant FF, kazkas panasaus jeigu buvo nutraukta užklausa, tai sekanti užklausa nebūdavo vykdoma (ant Opera ir IE be problemų). Internete radau sprendimą:

    var browser = navigator.appName;
    if (http.readyState==1) {
    if (browser != “Microsoft Internet Explorer”) {
    http.onreadystatechange = function() {};
    }
    http.abort();
    }

    ir tada viskas veikia be problemų.

  14. Martynas J.

    Naudojate low level AJAX ir patys turite rūpintis skirtingų naršyklių palaikymu. JavaScript biblioteka “Prototype” perkelia programuotoją į aukštesnį lygį, išspręsdama daug problemų — http://www.prototypejs.org/. Yra ir daugiau JS bibliotekų, tačiau ši man patinka labiausiai.


  15. Martynas J. - tu visiškai teisus, pats naudoju http://www.prototypejs.org/, bet, manau yra visiškai sveikia susipažinti su pagrindais, kad programuotojai žinotu kaip ši magija veikia.

    Asmeniškai pats pradėjau nuo to LOW LEVEL AJAX, po to pabandžiau susikurti savo biblioteka, o po to perejau prie prototype.js (nes tuo metu labai domejausi Ruby on Rails).

  16. NeWorld

    off-topic, jaučiu man irgi reikės pradėt pratintis prie frameworkų

  17. plyz

    Sveiki!!!
    Reikia pagalbos. Kur tiksliai reikia nustatyti koduote ? ir is vis o gal neveikia su win-1257 ???

  18. eSito

    Šis dalykas man veikia, bet norėjau paklaust kai meginu spaudžiu gerai gerai bet nieko nepasikeitė ar neturėtu parašyt tinkamas arkasnors panašaus?

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.