Odgovori znanstvenika html. Opis objekta Response. Pitajte profesora Markupa

Prijevod: Vlad Merzhevich

Svi znaju za web obrasce, zar ne? Umetnemo oznaku, nekoliko, možda, sve to upotpunimo gumbom i gotovi ste.

Ne znaš ni pola toga. HTML5 definira više od desetak novih vrsta polja koje možete koristiti u svojim obrascima. A kad kažem "upotrijebiti", mislim da se mogu upotrijebiti odmah - bez ikakvih trikova, hakiranja ili rješenja. Ne brinite previše, ne kažem da su sve ove uzbudljive nove značajke zapravo podržane u svakom pregledniku. Apsolutno ne, ne mislim na sve. U modernim preglednicima, da, vaši će obrasci pokazati sve za što su sposobni. Ali u starijim preglednicima vaši će obrasci i dalje raditi, iako ne u punom potencijalu. Odnosno, te značajke graciozno degradiraju u svakom pregledniku. Čak iu IE6.

Promptni tekst Brza tekstualna podrška
tj. Firefox Safari Krom Opera iPhone Android
- 4.0+ 4.0+ 4.0+ 11.0+ 4.0+ -

Prvo HTML5 poboljšanje u vezi s obrascima je mogućnost postavljanja brzog teksta u polje za unos. Ovaj tekst se prikazuje u polju za unos ako je polje prazno i ​​nema fokus. Čim kliknete na polje za unos (ili dođete do njega preko kartice), tekst savjeta nestaje.

Vjerojatno ste već vidjeli tekst upita. Na primjer, Mozilla Firefox uključuje tekst savjeta u adresna traka s natpisom "Traži u oznakama i dnevniku."

Kada kliknete na adresnu traku, tekst savjeta nestaje.

Evo kako možete uključiti sugestivan tekst u svoje obrasce.




Preglednici koji ne podržavaju atribut rezerviranog mjesta jednostavno ga ignoriraju. Bez štete ili kršenja.

Pitajte profesora Markupa

☞ P. Mogu li koristiti HTML označavanje za atribut rezerviranog mjesta? Želim umetnuti sliku ili možda promijeniti boje.

O. Atribut rezerviranog mjesta može sadržavati samo tekst, bez HTML koda. Međutim, postoje posebna CSS proširenja koja vam omogućuju postavljanje stila teksta u nekim preglednicima.

Polja autofokusa Podrška za autofokus
tj. Firefox Safari Krom Opera iPhone Android
- - 4.0+ 3.0+ 10.0+ - -

Web stranice mogu koristiti JavaScript za automatsko primanje fokus u prvom polju obrasca. Na primjer, na glavnoj stranici Google.com Polje za unos ključnih riječi za pretraživanje ima autofokus. Iako je to pogodno za većinu ljudi, može biti neugodno za napredne korisnike i osobe s posebnim potrebama. Ako pritisnete razmaknicu dok čekate da se stranica pomakne, neće biti pomicanja jer je fokus na polju za unos obrasca (umjesto pomicanja u polje će se unijeti razmak). Ako premjestite fokus na drugo polje za unos dok se stranica učitava, skripta za autofokus web mjesta može "od pomoći" pomaknuti fokus natrag na izvorno polje za unos, prekidajući vaše tipkanje i uzrokujući da tipkate na krivom mjestu.

Budući da autofokus radi putem JavaScripta, može doći do poteškoća s rukovanjem ovim ekstremnim slučajevima i malim opcijama za one ljude koji ne žele da im web stranica "ukrade" fokus.

Kako bi riješio te probleme, HTML5 uvodi atribut autofokusa za sve elemente obrasca. Atribut autofokusa radi točno ono što zvuči: čim se stranica učita, premješta fokus na navedeno polje. No budući da je ovo samo oznaka, a ne skripta, ponašanje će biti dosljedno na svim web-lokacijama. Osim toga, proizvođači preglednika (ili autori proširenja) mogu ponuditi korisnicima način da onemoguće autofokus.

Evo kako možete postaviti polje obrasca na autofokus.




Preglednici koji ne podržavaju atribut autofokusa zanemarit će ga.

Što se dogodilo? Recimo da želite da autofokus radi posvuda, ne samo u otmjenim HTML5 preglednicima? Možete ostaviti trenutnu skriptu s autofokusom, samo napravite dvije male promjene:

  • dodajte atribut autofokusa u HTML kod;
  • Provjerite podržava li preglednik atribut autofokusa, a ako ne, pokrenite vlastitu skriptu.

Autofokus s alternativom




if (!("autofocus" u dokumentu.createElement("input")) ) (
document.getElementById("q").focus();
}


Postavite fokus rano

Mnoge web stranice čekaju da se window.onload aktivira i postavi fokus. Ali događaj window.onload neće se pokrenuti dok se sve slike ne učitaju. Ako vaša stranica ima puno slika, takve naivne skripte potencijalno će promijeniti fokus nakon što korisnik započne interakciju s drugim dijelom vaše stranice. To je razlog zašto napredni korisnici mrze skripte za autofokus.

Na primjer, u prethodnom odjeljku, skripta za autofokus postavljena je odmah nakon polja obrasca na koje se odnosi. Ovaj optimalno rješenje, ali može uvrijediti vaš senzibilitet ako stavite blok JavaScript koda na sredinu stranice (ili što je običnije, vaš sustav možda nije toliko fleksibilan). Ako ne možete umetnuti skriptu u sredinu stranice, trebali biste postaviti fokus putem prilagođenog događaja kao što je $(document).ready() u jQuery umjesto window.onload.

Autofokus putem jQueryja




$(dokument).ready(funkcija() (

$("#q").fokus();
}
});






Prilagođeni događaj jQuery aktivira se čim DOM postane dostupan - to jest, čeka da se učita tekst stranice, ali ne čeka da se učitaju sve slike. Ovo nije optimalan pristup – ako je stranica neobično velika ili Mrežna veza sporo, korisnik može još uvijek biti u interakciji sa stranicom prije nego što se izvrši skripta fokusa. Ali to je još uvijek puno bolje nego čekati da se dogodi događaj window.onload.

Ako se slažete i voljni ste umetnuti skriptu s jednom naredbom u kôd svoje stranice, ovo je kompromis koji je manje gadan od prve opcije i bolji od druge. Možete koristiti jQuery prilagođene događaje za postavljanje vlastitih događaja, recimo autofocus_ready. Zatim možete ručno pokrenuti ovaj događaj čim polje autofokusa postane dostupno. Hvala E.M. Shtenbergu što me naučio ovu tehniku.

Autofokus s alternativnim prilagođenim događajem




$(dokument).bind("autofocus_ready", function() (
if (!("autofocus" u dokumentu.createElement("input")))) (
$("#q").fokus();
}
});





$(dokument).trigger("autofocus_ready");

Ovo rješenje je optimalno, kao i prvi pristup. Fokus će biti postavljen na polje obrasca čim to tehnički bude moguće dok se tekst stranice još učitava. Dio logike aplikacije (fokus u polju obrasca) premješten je iz tijela stranice u odjeljak. Ovaj se primjer temelji na jQueryju, ali koncept prilagođenih događaja nije jedinstven za jQuery. Druge JavaScript biblioteke poput YUI i Dojo nude slične mogućnosti.

Sažmimo.

  • Važno je pravilno postaviti fokus.
  • Ako je moguće, neka preglednik koristi atribut autofokusa na polju na kojem želite fokus.
  • Ako koristite alternativni kod za starije preglednike, definirajte podršku za atribut autofokusa tako da se skripta izvodi samo u starijim preglednicima.
  • Postavite fokus što je ranije moguće. Umetnite skriptu fokusa u kod odmah nakon polja obrasca. Ako vam to ne smeta, ugradite JavaScript biblioteku koja podržava prilagođene događaje i podignite događaj u kodu odmah nakon polja obrasca. Ako to nije moguće, upotrijebite događaj poput $(document).ready() iz jQueryja.
  • Ni pod kojim okolnostima ne biste trebali čekati da window.onload dobije fokus.
Adrese E-mail

Više od desetljeća obrasci su sadržavali samo nekoliko vrsta polja. Najčešći su sljedeći.

Sve ove vrste polja i dalje rade u HTML5. Ako "nadogradite na HTML5" (možda promjenom !DOCTYPE), nećete morati napraviti niti jednu promjenu na svojim obrascima. Bravo za kompatibilnost sa prethodnim verzijama!

Međutim, HTML5 definira 13 novih vrsta polja i nema razloga da ih ne počnete koristiti.

Prva od ovih novih vrsta adresa e-pošte. Izgleda otprilike ovako.





Htjela sam napisati rečenicu koja je počela "na preglednicima koji ne podržavaju type="email" ..." ali sam stala. Zašto? Jer nisam siguran podržavaju li preglednici type="email" . Svi preglednici "podržavaju" type="email" . Možda neće učiniti ništa posebno, ali preglednici koji ne prepoznaju type="email" tretirat će ga kao type="text" i prikazati ga kao normalno tekstualno polje.

Naglasit ću koliko je to važno. Postoje milijuni obrazaca na internetu koji od vas traže da unesete svoju adresu e-pošte, a svi oni koriste . Vidite tekstni okvir, unesite svoju e-mail adresu u njega i to je to. A onda dolazi HTML5, koji definira type="email" . Jesu li preglednici poludjeli? Ne. Svaki preglednik na Zemlji tretira atribut nepoznate vrste kao type="text" - čak i IE6. Dakle, možete "osvježiti" svoje obrasce koristeći type="email" upravo sada.

Što se događa ako kažemo da preglednik podržava type="email"? Pa, moglo bi značiti bilo što. HTML5 specifikacija ne zahtijeva nikakvo posebno korisničko sučelje za nove vrste polja. Opera dodaje malu ikonu u polje obrasca. Drugi HTML5 preglednici poput Safarija i Chromea prikazuju se kao tekstualno polje - isto kao type="text" - tako da vaši korisnici neće primijetiti razliku (sve dok ne pogledaju izvorni kod).

A tu je i iPhone.

iPhone nema fizičku tipkovnicu. Sve se "tipka" vrši klikom na zaslonsku tipkovnicu koja se pojavljuje u odgovarajućem trenutku, na primjer, kada odete na polje obrasca na web stranici. Apple je napravio nešto pametno iPhone preglednik. Prepoznaje neka nova HTML5 polja i dinamički mijenja zaslonsku tipkovnicu kako bi optimizirao unos.

Na primjer, adresa e-pošte je tekst, zar ne? Naravno, ali ovo je posebna vrsta teksta. Tako gotovo sve adrese e-pošte sadrže simbol @ i, prema barem, jednu točku (.), ali je malo vjerojatno da će sadržavati razmak. Dakle, kada koristite iPhone i odete na , dobit ćete zaslonsku tipkovnicu koja uključuje manju razmaknicu kao i namjenske tipke za simbole. I @.

Dopustite mi da to sažmem. Nema loše strane odmah prevesti sva vaša polja s email adrese u type="email" . Gotovo nitko to neće primijetiti osim korisnika iPhonea, koji to vjerojatno neće ni primijetiti. Ali oni koji to primijete tiho će se nasmiješiti i zahvaliti što ste im barem malo olakšali posao.

Web adrese

Web adresa—koju su štreberi po standardima nazivali URL-ovima, osim nekolicine pedanata koji su nazivali URI-jima—druga je vrsta specijaliziranog teksta. Sintaksa web adrese ograničena je relevantnim internetskim standardom. Ako vas netko zatraži da unesete web adresu u obrazac, očekuje nešto poput "http://www.google.com/", a ne "125 Farwood Road". Kose linije su česte - čak i u početna stranica Google ih ima tri. Točke su također uobičajene, ali razmaci su zabranjeni. A svaka web adresa ima nastavak domene poput ".com" ili ".org".

I tako... (drum roll please)... . Na iPhoneu to izgleda ovako.

iPhone je promijenio svoje virtualna tipkovnica, baš kao što sam učinio za adresu e-pošte, ali sam ga sada optimizirao za upisivanje web adrese. Razmaknicu su u potpunosti zamijenile tri virtualne tipke: kosa crta, točka i ".com" (možete držati pritisnutu tipku ".com" da biste odabrali drugi sufiks poput ".org" ili ".net").

Preglednici koji ne podržavaju HTML5 tretirat će type="url" kao type="text" , tako da nema nedostataka u korištenju ove vrste za sva polja u koja trebate unijeti web adresu.

Brojevi kao brojači

Sljedeći korak: brojevi. Zahtjev za brojem je složeniji od zahtjeva za e-poštom ili web adresom. Prije svega, brojevi su složeniji nego što mislite. Brzo odaberite broj. -1? Ne, mislio sam na broj između 1 i 10,7 ½? Ne, ne, ne budi razlomak, glupane. π? Sada ste upravo odabrali iracionalan broj.

Želio bih napomenuti da vas ne pitaju često "samo broj". Vjerojatnije je da će tražiti broj u određenom rasponu. Možda želite samo određene vrste brojeva unutar ovog raspona - možda cijele brojeve, ali ne razlomke ili decimalni brojevi ili nešto egzotičnije, poput višekratnika od 10. HTML5 pokriva sve.

Odaberite broj, gotovo bilo koji

Pogledajmo jedan po jedan atribut.

  • type="number" znači da je ovo numeričko polje.
  • min="0" navodi minimalnu dopuštenu vrijednost za ovo polje.
  • max="10" je najveća dopuštena vrijednost.
  • step="2" u kombinaciji s minimalnom vrijednošću definira važeće brojeve u rasponu: 0, 2, 4 i tako dalje, do maksimalne vrijednosti.
  • value="6" zadana vrijednost. Trebalo bi izgledati poznato, ovo je isti atribut koji se uvijek koristi za definiranje vrijednosti polja obrasca. Spominjem ovo ovdje kao početnu točku na kojoj se temelji HTML5 prethodne verzije HTML. Ne morate ponovno učiti raditi ono što ste već učinili.

Ovo je kod za numeričko polje. Imajte na umu da su svi ovi atributi izborni. Ako imate minimum, ali ne i maksimum, možete navesti atribut min, ali ne i maksimum. Zadana vrijednost koraka je 1 i možete izostaviti atribut koraka dok ne bude potrebna druga vrijednost koraka. Ako nema zadane vrijednosti, atribut vrijednosti može biti prazna linija ili čak posve izostavljena.

Ali HTML5 tu ne staje. Za istu nisku niska cijena slobodu koju dobivate s ovim praktičnim JavaScript metodama.

  • input.stepUp(n) povećava vrijednost polja za n.
  • input.stepDown(n) smanjuje vrijednost polja za n.
  • input.valueAsNumber vraća trenutnu vrijednost kao broj s pomičnim zarezom (svojstvo input.value uvijek je niz).

Problemi s prikazom? Pa, ispravno sučelje za upravljanje brojevima drugačije je implementirano u preglednicima. Na iPhoneu, gdje je tipkanje otežano, preglednik ponovno optimizira virtualnu tipkovnicu za unos brojeva.

U desktop verziji Opere polje type="number" pojavljuje se kao brojač s malim strelicama gore i dolje na koje možete kliknuti da biste promijenili vrijednosti.

Opera poštuje atribute min , max i step, tako da ćete uvijek postići prihvatljivu numeričku vrijednost. Ako povećate vrijednost do maksimuma, strelica prema gore u brojaču postaje siva.

Kao i sa svim ostalim poljima za unos o kojima sam govorio u ovom poglavlju, preglednici koji ne podržavaju type="number" tretirat će ga kao type="text" . Zadana vrijednost bit će prikazana u polju (jer je pohranjena u atributu vrijednosti), ali ostali atributi kao što su min i max bit će zanemareni. Možete ih sami implementirati ili koristiti JavaScript okvir koji već implementira upravljanje brojačem. Prvo provjeri ovdje.

if (! .inputtypes.number) (
// nema izvorne podrške za polje type=number
// možete isprobati Dojo ili neki drugi JavaScript okvir
}

Brojevi kao klizač

Brojač nije jedini način prikazi unosa brojeva. Vjerojatno ste također vidjeli slider koji izgleda ovako.

Sada možete imati i klizač na obrascu. Kod izgleda neobično sličan polju brojača.


Svi dostupni atributi isti su kao za type="number" - min, max, step, value - i znače isto. Jedina je razlika korisničko sučelje. Umjesto polja za unos, od preglednika se očekuje da prikazuju type="range" kao klizač. U vrijeme pisanja najnovije verzije Safari, Chrome i Opera radili su s ovim. Nažalost, iPhone se prikazuje kao jednostavan polje za tekst, čak ni ne optimizira svoju zaslonsku tipkovnicu za unos brojeva. Svi ostali preglednici jednostavno tretiraju polje kao type="text" , tako da nema razloga da odmah počnete koristiti ovaj tip.

HTML 4 ne uključuje odabir datuma putem kalendara. JavaScript okviri vam omogućuju da to zaobiđete (Dojo, jQuery UI, YUI, Closure Library), ali, naravno, svako od ovih rješenja zahtijeva "implementaciju" okvira za bilo koji ugrađeni kalendar.

HTML5 konačno definira način za omogućavanje izvornih birača datuma bez ikakvog skriptiranja. Zapravo ih je šest: datum, mjesec, tjedan, vrijeme, datum + vrijeme i datum + vrijeme s vremenskom zonom.

Do sada je podrška... oskudna.

Podrška za odabir datuma Upišite Opera Ostali preglednici
tip="datum" 9.0+ -
tip="mjesec" 9.0+ -
tip="tjedan" 9.0+ -
tip="vrijeme" 9.0+ -
tip="datumvrijeme" 9.0+ -
type="datetime-local" 9.0+ -

Evo kako Opera prikazuje:

Ako trebate vrijeme uz datum, Opera također podržava:

Ako trebate mjesec plus godinu (na primjer, datum isteka kreditne kartice), Opera može prikazati:

Manje uobičajeno, ali dostupno, je odabir tjedna u godini putem:

Posljednje, ali ne manje važno, je vrijeme s:

Birač datuma s alternativom




...

var i = document.createElement("ulaz");
i.setAttribute("vrsta", "datum");
if (i.type == "text") (
// Nema izvorne podrške za odabir datuma :(
// Koristite Dojo/jQueryUI/YUI/Closure za stvaranje,
// zatim dinamički zamijeniti element
}

Vjerojatno će drugi preglednici s vremenom podržavati te vrste. Kao i type="email" i druge vrste, ova polja obrasca pojavit će se kao običan tekst u preglednicima koji ne prepoznaju type="date" i njegove varijante. Ako želite, možete jednostavno koristiti , usrećiti korisnike Opere i pričekati da ih drugi preglednici sustignu. Realističnije je koristiti ovo, ali provjerite ima li preglednik izvornu podršku za odabir datuma i uključite alternativno rješenje u obliku skripte po vašem izboru (Dojo, jQuery UI, YUI, Closure Library ili druge opcije).

Prozor za pretraživanje

Dakle, traži. Ne samo pretraživanja s Googlea ili Yahooa (dobro, i njih). Razmislite o bilo kojem okviru za pretraživanje, na bilo kojoj stranici, na bilo kojoj web stranici. Amazon ima okvir za pretraživanje, Yandex ima okvir za pretraživanje, većina blogova također. Kako se izrađuju? , kao i svako drugo tekstno polje na webu. Popravimo ovo.

Potraga za novom generacijom




U nekim preglednicima nećete primijetiti nikakvu razliku u odnosu na obično tekstualno polje. Ali ako koristite Safari na Mac OS X, izgledat će ovako.

Jeste li pronašli razliku? Polje za unos ima zaobljene kutove! Znam, znam, teško možeš obuzdati svoje osjećaje. Ali čekaj, ima još! Kada počnete upisivati ​​type="search" u polje, Safari će umetnuti mali "x" gumb na desnoj strani prozora. Klikom na "x" briše se sadržaj polja. Google Chrome, koji ima istu tehnologiju ispod haube, ponaša se na isti način. Oba ova mala trika izgledaju i ponašaju se slično izvornom pretraživanju u iTunesu i drugim Mac OS X klijentskim aplikacijama.

Apple.com koristi pretraživanje web-mjesta kako bi web-mjesto prenijelo osjećaj "ljubitelja ara". Ali ovdje nema ničeg specifičnog za Macove. To je samo kod, tako da svaki preglednik na svakoj platformi može odabrati način prikazivanja u skladu s konvencijama platforme. Kao i sa svim drugim novim vrstama, preglednici koji ne prepoznaju type="search" tretirat će ga kao type="text" , tako da nema apsolutno nikakvog razloga da ne počnete koristiti type="search" za sve svoje okvire za pretraživanje danas.

Kaže profesorica Markap

Safari prema zadanim postavkama ne primjenjuje većinu stilova. Ako želite natjerati Safari da tretira polje za pretraživanje kao uobičajeno polje teksta (tako da možete primijeniti vlastite stilove), dodajte ovo pravilo svojoj tablici stilova.

ulazni(
-webkit-appearance:textfield;
}

Hvala Johnu Laneu što me naučio ovom triku.

Izbor boja

HTML5 također definira polje koje vam omogućuje odabir boje i vraća je u heksadecimalnom obliku. Nijedan preglednik ne podržava birače boja, što je šteta jer sam uvijek volio Mac OS palete. Možda jednog dana.

Bilješka prevoditelj Opera 11 podržava ovu značajku.

Provjera valjanosti obrasca

U ovom poglavlju govorio sam o novim elementima obrasca i novim značajkama poput autofokusa, ali nisam spomenuo možda najuzbudljiviji dio HTML5 obrazaca: automatska provjera ulazni podaci. Razmotrimo uobičajeni problemi unosom vaše e-mail adrese u obrazac. Vjerojatno imate provjeru valjanosti na strani klijenta putem JavaScripta, nakon čega slijedi provjera valjanosti na strani poslužitelja putem PHP-a, Pythona ili drugog jezika na strani poslužitelja. HTML5 nikada neće zamijeniti provjeru valjanosti na strani poslužitelja, ali bi jednog dana mogao zamijeniti provjeru valjanosti na strani klijenta.

Postoje dva velika problema s provjerom adrese e-pošte u JavaScriptu:

  • Mali broj vaših posjetitelja (vjerojatno oko 10%) nema omogućen JavaScript.
  • Dobit ćete pogrešnu adresu.
  • Ozbiljno, pogriješit ćete adresu. Nevjerojatno je teško utvrditi da je skup nasumičnih znakova važeća adresa e-pošte. Što teže gledate, to postaje teže. Jesam li spomenuo da je ovo jako, jako teško? Nije li lakše objesiti ovu glavobolju na vaš preglednik?

    Opera provjerava type="email"

    Ovdje je snimak zaslona iz Opere 11, iako je funkcija prisutna od Opere 9. Kod uključuje postavljanje vrijednosti e-pošte za atribut tipa. Kada korisnik Opere pokuša poslati obrazac s , preglednik automatski provjerava adresu e-pošte, čak i ako su skripte onemogućene.

    HTML5 također nudi provjeru valjanosti web adresa s poljem i brojeva s . Validacija broja uzima u obzir vrijednosti atributa min i max, tako da vam preglednici neće dopustiti da pošaljete obrazac ako unesete broj koji je prevelik.

    Ne postoji kôd koji omogućuje provjeru valjanosti obrasca u HTML5, to se radi prema zadanim postavkama. Da biste onemogućili provjeru valjanosti, koristite atribut novalidate.

    Nemoj me testirati




    Preglednici sporo uključuju podršku za provjeru valjanosti obrasca u HTML5. Firefox 4 će imati punu podršku. Nažalost, Safari i Chrome implementirani su samo djelomično: provjeravaju elemente obrasca, ali ne prikazuju nikakve vidljive poruke kada polje obrasca ne prođe provjeru. Drugim riječima, ako unesete netočan (ili pogrešno napisan) datum u type="date" , Safari i Chrome neće poslati obrazac, ali vam neće reći zašto nisu. Oni će postaviti fokus na polje koje sadrži nevažeću vrijednost, ali neće prikazati poruku o pogrešci kao Opera ili Firefox 4.

    Obavezna polja podrška
    tj. Firefox Safari Krom Opera iPhone Android
    - 4.0+ - - 9.0+ - -

    Provjera valjanosti obrasca u HTML5 nije ograničena na vrstu svakog polja. Također možete navesti da su neka polja obavezna, takva polja moraju imati vrijednost prije nego što možete poslati obrazac.

    Kôd za obavezna polja je najjednostavniji.




    Preglednici mogu promijeniti izvorni izgled obaveznog polja. Evo primjera kako to izgleda u Mozilla Firefoxu 4.0.

    Osim toga, ako pokušate poslati obrazac bez ispunjavanja potrebne vrijednosti, Firefox će prikazati informacijsku traku koja govori da je polje obavezno i ​​ne može biti prazno.

    Generiranje odgovora kontrolora

    Nakon što kontroler završi s obradom zahtjeva, obično treba generirati odgovor. Kada kreiramo kontroler niske razine izravnom implementacijom sučelja IController, moramo preuzeti odgovornost za svaki aspekt obrade zahtjeva, uključujući generiranje odgovora klijentu.

    Na primjer, da biste poslali HTML odgovor, trebali biste stvoriti i sastaviti HTML podatke i zatim ih poslati klijentu pomoću metode Response.Write(). Slično tome, da biste preusmjerili korisnikov preglednik na drugi URL, morat ćete pozvati metodu Response.Redirect() i proslijediti joj traženi URL. Oba su pristupa prikazana u donjem kodu, koji prikazuje proširenja klase BasicController koju smo stvorili u ranijem članku implementacijom sučelja IController:

    Korištenje System.Web.Mvc; koristeći System.Web.Routing; namespace ControllersAndActions.Controllers ( public class BasicController: IController ( public void Execute(RequestContext requestContext) ( string controller = (string)requestContext.RouteData.Values["controller"]; string action = (string)requestContext.RouteData.Values["action "]; if (action.ToLower() == "redirect") ( requestContext.HttpContext.Response.Redirect("/Derived/Index"); ) else ( requestContext.HttpContext.Response.Write(string.Format("Controller) : (0), Metoda akcije: (1)", kontroler, akcija)); ) ) ) )

    Isti pristup može se primijeniti u slučaju nasljeđivanja kontrolera iz klase Controller. Klasi HttpResponseBase, koja se vraća kada se svojstvo requestContext.HttpContext.Response pročita u metodi Execute(), dostupno je putem svojstva Controller.Response, kao što je prikazano u donjem primjeru, koje proširuje klasu DerivedController, koju je također ranije stvorio nasljeđujući od klase Controller:

    Korištenje sustava; koristeći System.Web; koristeći System.Web.Mvc; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public void ProduceOutput() ( if (Server.MachineName == "ProfessorWeb") Response.Redirect("/Basic/Index" ); else Response.Write("Kontroler: Izvedeno, Metoda akcije: ProduceOutput"); ) ) )

    Metoda ProduceOutput() koristi vrijednost svojstva Server.MachineName da odluči koji odgovor poslati klijentu. ("ProfessorWeb" je naziv mog razvojnog stroja.)

    Iako ovaj pristup generiranja odgovora korisniku funkcionira, postoji nekoliko problema s njim:

      Klase kontrolera moraju sadržavati informacije o HTML struktura ili URL, što čini klase teškima za čitanje i održavanje.

      Kontroler koji generira odgovor izravno na izlaz teško je jedinično testirati. Morat ćete stvoriti lažne implementacije Response objekta i zatim moći obraditi izlaz iz kontrolera da odredite što je to. To može značiti, na primjer, potrebu za raščlanjivanjem HTML oznaka u ključne riječi, što je dug i naporan proces.

      Obrada malih detalja svakog odgovora na ovaj način složena je i podložna pogreškama. Neki programeri vole apsolutnu kontrolu koju pruža izgradnja kontrolera niske razine, ali to se obično vrlo brzo zakomplicira.

    Srećom, MVC Framework ima zgodan alat koji rješava sve te probleme - rezultate radnji. Sljedeći odjeljci objašnjavaju koncept rezultata akcije i pokazuju razne načine njegovu upotrebu za generiranje odgovora kontrolora.

    Rezultati radnji

    Rezultati akcije u MVC okviru koriste se za odvajanje izjava o namjerama od izvršenja namjere (oprostite na tautologiji). Koncept će se činiti jednostavnim nakon što ga shvatite, ali potrebno je neko vrijeme da ga shvatite zbog neke neizravnosti.

    Umjesto da se izravno bave objektom Response, radnje metode vraćaju objekt klase izveden iz ActionResult-a koji opisuje kakav bi trebao biti odgovor kontrolera—na primjer, renderiranje prikaza ili preusmjeravanje na drugi URL ili metodu radnje. Međutim (to je sama neizravnost) odgovor nije izravno generiran. Umjesto toga, stvara se objekt ActionResult, koji MVC Framework obrađuje da proizvede rezultat nakon što je pozvana metoda akcije.

    Sustav rezultata akcije primjer je uzorka dizajna naredbe. Ovaj uzorak predstavlja scenarije u kojima pohranjujete i prosljeđujete objekte koji opisuju operacije koje se izvode.

    Kada MVC Framework primi ActionResult objekt od radnje metode, on poziva ExecuteResult() metoda, definiran u klasi ovog objekta. Implementacija rezultata radnje tada djeluje na objektu Response, generirajući izlaz koji odgovara vašoj namjeri. Da bismo to demonstrirali na djelu, stvorimo mapu Infrastruktura i dodamo joj novu datoteku klase pod nazivom CustomRedirectResult.cs s prilagođenom implementacijom ActionResult prikazanom u primjeru u nastavku:

    Korištenje System.Web.Mvc; namespace ControllersAndActions.Infrastructure ( public class CustomRedirectResult: ActionResult ( public string Url ( get; set; ) public override void ExecuteResult(ControllerContext context) ( string fullUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext); context.HttpContext.Response.Redirect (puniUrl); ) ) )

    Ova se klasa temelji na načinu na koji funkcionira klasa System.Web.Mvc.RedirectResult. Jedna od prednosti otvoreni izvor MVC Framework se bavi mogućnostima istraživanja unutarnjeg funkcioniranja bilo čega. Klasa CustomRedirectResult mnogo je jednostavnija od svog MVC ekvivalenta, ali je dovoljna za potrebe ovog članka.

    Prilikom instanciranja klase RedirectResult, prosljeđujemo URL na koji korisnik treba biti preusmjeren. Metoda ExecuteResult(), koju će izvršiti MVC Framework kada se radnja metoda završi, prima Response objekt za zahtjev kroz Frameworkov ControllerContext objekt i poziva ili RedirectPermanent() metodu ili Redirect() metodu (ovo je točno ono što je učinjeno unutar implementacije IControllera na niskoj razini u primjeru ranije u članku).

    Korištenje klase CustomRedirectResult ilustrirano je u primjeru u nastavku, koji prikazuje promjene koje su napravljene na Izvedenom kontroleru:

    // ... using ControllersAndActions.Infrastructure; namespace ControllersAndActions.Controllers ( public class DerivedController: Controller ( public ActionResult Index() ( // ... ) public ActionResult ProduceOutput() ( if (Server.MachineName == "MyMachineName") return new CustomRedirectResult ( Url = "/Basic/ Indeks" ); else ( Response.Write("Kontroler: Izvedeno, Metoda akcije: ProduceOutput"); return null; ) ) ) )

    Imajte na umu da smo bili prisiljeni promijeniti rezultat metode akcije da vrati ActionResult. Vraćamo null ako ne želimo da MVC Framework radi bilo što kada se izvrši naša radna metoda, što smo učinili ako instanca CustomRedirectResult nije vraćena.

    Kontrolori i radnje za testiranje jedinice

    Mnogi dijelovi MVC okvira dizajnirani su za lakše testiranje jedinica, a to posebno vrijedi za akcije i kontrolere. Postoji nekoliko razloga za ovu podršku:

    Radnje i kontrolere možete testirati izvan web poslužitelja. Objektima konteksta pristupa se kroz njihove osnovne klase (kao što je HttpRequestBase), što je lako ismijati.

    Da biste testirali rezultate radnje metode, ne morate analizirati HTML oznake. Kako biste bili sigurni da dobivate očekivane rezultate, možete pregledati vraćeni objekt ActionResult.

    Nije potrebna emulacija zahtjeva klijenata. Sustav vezivanja modela okvira MVC omogućuje vam pisanje metoda radnji koje primaju unos u svojim parametrima. Da biste testirali akcijsku metodu, jednostavno je pozovite izravno i navedite odgovarajuće vrijednosti parametra.

    Budući članci o generiranju podataka iz kontrolera pokazat će vam kako izraditi jedinične testove za različite vrste rezultata radnji.

    Ne zaboravite da je jedinično testiranje samo dio slike. Složeno ponašanje u aplikaciji događa se kada se akcijske metode pozivaju uzastopno. Jedinično testiranje najbolje funkcionira u kombinaciji s drugim pristupima testiranju.

    Sada kada znate kako funkcionira poseban rezultat akcije preusmjeravanja, možete se prebaciti na njegov ekvivalent koji nudi okvir MVC, koji je moćniji i temeljito ga je testirao Microsoft. Potrebna promjena izvedenog regulatora je navedena u nastavku:

    // ... public ActionResult ProduceOutput() ( return new RedirectResult("/Basic/Index"); ) // ...

    Uvjetna izjava je uklonjena iz metode akcije, što znači da će nakon pokretanja aplikacije i navigacije do URL-a kao što je /Derived/ProduceOutput, preglednik biti preusmjeren na URL kao što je /Basic/Index. Kako bi se pojednostavio kod metode akcije, klasa Controller uključuje praktične metode za generiranje raznih vrsta ActionResult objekata. Tako, na primjer, možemo postići isti učinak kao u gornjem primjeru vraćanjem rezultata metode Redirect():

    // ... public ActionResult ProduceOutput() ( return Redirect("/Basic/Index"); ) // ...

    Nema ništa posebno složeno u sustavu rezultata akcije, ali u konačnici pomaže u stvaranju jednostavnijeg, čišćeg i dosljednijeg koda koji je jednostavan za čitanje i jedinično testiranje. Na primjer, u slučaju preusmjeravanja, možete jednostavno provjeriti vraća li metoda radnje instancu RedirectResult čije svojstvo Url sadrži očekivani cilj.

    MVC Framework definira mnoge ugrađene tipove rezultata radnji, koji su opisani u tablici u nastavku:

    Ugrađene vrste ActionResult Tip Opis Pomoćne metode klase Controller
    ViewResult

    Renderira navedeni ili standardni predložak prikaza

    Pogled()
    PartialViewResult

    Iscrtava navedeni ili standardni predložak djelomičnog prikaza

    Djelomični prikaz()
    RedirectToRouteResult

    Problemi HTTP preusmjeravanje 301 ili 302 na akcijsku metodu ili određeni unos rute, generiranje URL-a prema konfiguraciji usmjeravanja

    Preusmjeri na radnju()
    RedirectToActionPermanent()
    RedirectToRoute()
    RedirectToRoutePermanent()
    RedirectResult

    Izdaje HTTP 301 ili 302 preusmjeravanje na navedeni URL

    Preusmjeri()
    RedirectPermanent()
    ContentResult

    Vraća neformatirane tekstualne podatke pregledniku, dodatno postavljajući zaglavlje vrste sadržaja

    Sadržaj()
    FileResult

    Prenosi binarne podatke (kao što je datoteka na disku ili niz bajtova u memoriji) izravno u preglednik

    Datoteka()
    JsonResult

    Serializira .NET objekt u JSON format i šalje kao odgovor. Odgovori ove vrste češće se generiraju korištenjem Web API i AJAX alata

    Json()
    JavaScriptResult

    Šalje dio JavaScript izvornog koda koji preglednik treba izvršiti

    JavaScript()
    HttpUnauthorizedResult

    Postavlja šifru statusa HTTP odgovora na 401 (što znači "nije ovlašteno"), što uzrokuje da mehanizam provjere autentičnosti (provjera autentičnosti obrasca ili Windows provjera autentičnosti) traži od posjetitelja da se prijavi

    Ne
    HttpNotFoundResult

    Povratak HTTP greška sa šifrom 404 - Nije pronađeno (nije pronađeno)

    HttpNotFound()
    HttpStatusCodeResult

    Vraća navedeni HTTP kod

    Ne
    EmptyResult

    Ne radeći ništa

    Ne

    Sve ove vrste proizlaze iz klase ActionResult, a mnoge od njih imaju prikladne pomoćne metode u klasi Controller. Pokazat ćemo korištenje ovih vrsta rezultata u sljedećim člancima.

    Opisani objekt je vrlo koristan i moćan alat. Ovaj objekt ima nekoliko metoda, njihov opis je dat u nastavku:

    Zbirke: Metode: Svojstva: Odgovor. Prikupljanje kolačića

    Kolekcija kolačića postavlja vrijednosti za kolačiće. Ako navedeni kolačići ne postoje, kreira ih. Ako kolačić postoji, on preuzima novu vrijednost i uništava staru.

    Odgovor.Kolačići(kolačić) [(ključ) | . atributi ] = vrijednost

    Mogućnosti:

    • kolačić - naziv kolačića
    • ključ - Izborni parametar. Ako je navedeno, kolačić je direktorij (ugniježđen), a ključ je skup vrijednosti.
    • atributi - Navedene informacije o samim kolačićima. Ovaj parametar može biti jedno od sljedećeg:
    • vrijednost - Određuje vrijednost koja će se dodijeliti ovom ključu ili atributu.
    ImeOpis
    DomenaSamo snimanje. Ako je navedeno, kolačići se šalju samo na zahtjev s ove domene.
    ističeSamo snimanje. Datum isteka kolačića. Ovaj datum mora biti postavljen kako bi se kolačići mogli pisati klijentu HDD nakon završetka sjednice. Ako ovaj atribut nije postavljen, tada se pretpostavlja datum isteka kolačića trenutni datum. Kolačići će isteći odmah nakon završetka sesije.
    HasKeySamo čitanje. Označava sadrži li kolačić navedeni ključ.
    StazaSamo snimanje. Ako je navedeno, kolačići se šalju samo na zahtjev s ove staze. Ako parametar nije postavljen, koristi se put do aplikacije.
    SiguranSamo snimanje. Pokazuje hoće li kolačići biti zaštićeni ili ne.

    Komentar:

    Ako je ključni kolačić kreiran kao što je prikazano u sljedećoj skripti,

    tada će biti poslano sljedeće zaglavlje:

    Set-Cookie:MYCOOKIE=TYPE1=šećer&TYPE2=kolačići

    Ako dodijelite vrijednost mycookie bez korištenja ključeva, tada će ova radnja uništiti tipke type1 i type2. npr.:

    U prethodnom primjeru, ključevi type1 i type2 će biti uništeni i njihove vrijednosti će biti izgubljene. Mycookie će sada sadržavati vrijedan čokoladni marshmallow.

    Također možete provjeriti postojanje određenog ključa na sljedeći način:

    Ako je prikazano TRUE, tada takav ključ postoji; ako je FALSE, ne postoji.

    Response.Write metoda

    Response.Write varijabla_ili_vrijednost

    Mogućnosti:

    • variable_or_value - Podaci koji će se prikazati na zaslonu preglednika putem HTML-a. Ovaj parametar može biti bilo koje vrste koju podržava VisualBasic Scripting Edition. Odnosno, podaci mogu biti sljedećih vrsta: datum, niz, znak, numeričke vrijednosti. Značenje ovaj parametar ne može sadržavati %> kombinacija. Umjesto toga, možete koristiti ekvivalentnu kombinaciju %\>. Web poslužitelj će ovu sekvencu pretvoriti u potrebnu kada se skripta izvrši.

    Sljedeći primjer pokazuje kako metoda Response.write radi na izlazu poruke klijentu.

    Samo ću ti reći: I tvoje ime

    Sljedeći primjer dodaje HTML oznaku na web stranicu. Budući da ova metoda ne može sadržavati kombinaciju %>, koristimo niz %\>. Dakle, primjer skripte:

    Izlaz će biti redak:

    Response.Redirect metoda

    Response.Redirect URL (URL - Uniform Resource Locator)

    Mogućnosti:

    • URL - Parametar je univerzalni deskriptor izvora. Prikazuje kada preglednik treba preusmjeriti.

    Komentar:

    Svaka pojava ovu metodu između oznaka i web stranice zanemarit će se. Ova se metoda može koristiti samo u zaglavlju HTML stranice. Ova će metoda proslijediti zaglavlje pregledniku ako URL parametar nedostaje ovog objekta u sljedećem obliku:

    HTTP/1.0 302 URL lokacije premještenog objekta

    Response.End metoda

    Odgovor.Kraj

    Komentar:

    Ako je svojstvo Response.Buffer postavljeno na TRUE, tada će pozivanje metode Response.End očistiti međuspremnik, gurajući podatke iz njega klijentu. Ako ne želite ispisati podatke korisniku, trebali biste pozvati sljedeću metodu:

    Metoda Response.AddHeader

    Metoda AddHeader dodaje HTML zaglavlje s određenim vrijednostima. Ova metoda uvijek dodaje novo zaglavlje odgovoru pregledniku klijenta. Ova metoda ne zamjenjuje postojeće zaglavlje novim. Dodano zaglavlje nije moguće ukloniti.

    Ova se metoda koristi samo za "napredne" zadatke.

    Response.AddHeader variable_name, value

    Mogućnosti:

    • variable_name - Naziv novih parametara HTML zaglavlja.
    • vrijednost - Postavite vrijednost koja će biti zapamćena u zaglavlju.
    Bilješke:

    Kako bi metoda radila ispravno, variable_name ne smije sadržavati znak podvlake (_). Skup ServerVariables tumači podvlaku kao crticu u zaglavlju. Kao primjer, sljedeća skripta prisiljava poslužitelj da pronađe parametar iz HTML zaglavlja pod nazivom MY-HEADER.

    Budući da HTTP protokol zahtijeva da se svi parametri zaglavlja proslijede prije tijela HTML stranice, morate pozvati metodu AddHeader u svojoj skripti prije početka opisa.... Postoji jedna iznimka. Ako je svojstvo Buffer postavljeno na true, tada možete napisati AddHeader bilo gdje u skripti, ali prije prvog poziva metode Flush. U suprotnom, pozivanje metode AddHeader pokrenut će pogrešku.

    Sljedeće dvije .ASP datoteke pokazuju ovu posljednju točku.

    svoj tekst na stranici

    U u ovom primjeru stranica nije u međuspremniku. Skripta radi, međutim AddHeader se poziva prije nego što poslužitelj proizvede HTML izlaz klijentu.

    evo par informacija sa tvoje stranice...

    U drugom primjeru, stranica je u međuspremniku i, kao rezultat toga, poslužitelj ne šalje tekst klijentu dok sama skripta ne završi ili se ne naiđe na metodu Flush. Ovu metodu možete koristiti za slanje više kopija nekog parametra zaglavlja s različitim vrijednostima, kao kod zaglavlja WWW-Authenticate.

    Metoda Response.AppendToLog

    Metoda AppendToLog dodaje redak na kraj datoteke izvješća (log-file) web poslužitelja. Ovu metodu možete pozvati onoliko puta koliko je potrebno. Svaki put kada pozovete metodu, niz koji navedete bit će zapisan u datoteku izvješća poslužitelja.

    Vrijednost Response.AppendToLog

    Mogućnosti:

    • vrijednost - Tekst koji će biti dodan u datoteku izvješća web poslužitelja. Ova linija ne može sadržavati znak zarez (,). Štoviše, ukupna duljina dodanog retka ne smije premašiti 80 znakova.
    Bilješke:

    Da biste koristili ovu značajku, morate imati omogućenu opciju URI Query na ploči "Advanced Logging Properties" za ovaj web poslužitelj u IIS-u.

    Response.BinaryWrite metoda

    Metoda BinaryWrite omogućuje vam pisanje određenih informacija u trenutni HTTP izlaz bez ikakve pretvorbe znakova. Ova je metoda korisna za ispisivanje informacija koje nisu nizovi, kao što su binarni podaci koje zahtijeva aplikacija.

    Response.BinaryWrite podaci

    Mogućnosti:

    • podaci - Podaci namijenjeni za HTTP izlaz.

    Ako imate objekt koji proizvodi niz bajtova, možete upotrijebiti sljedeći poziv ove metode za prosljeđivanje tog niza nekoj aplikaciji koja se izvodi na klijentskom računalu.

    Odgovor. Jasna metoda

    Metoda Clear briše sav HTML izlaz u međuspremniku. Međutim, ova metoda ne briše podatke međuspremnika povezane sa zaglavljem. Ovu metodu možete koristiti za upravljanje pogreškama. Međutim, izvođenje ove metode rezultirat će pogreškom ako svojstvo Response.Buffer nije istinito.

    Svojstvo Response.CacheControl

    Ovo svojstvo nadjačava zadanu vrijednost. Kada svojstvo postavite na Javno, proxy poslužitelj može predmemorirati izlaz koji je generirao ASP.

    Response.CacheControl [= kontrola predmemorije Zaglavlje]

    Mogućnosti:

    • Zaglavlje kontrole predmemorije - Ova opcija kontrole zaglavlja može biti javna ili privatna.
    Svojstvo Response.CharSet

    Svojstvo CharSet omogućuje vam dodavanje naziva tablice kodova znakova (na primjer, WINDOWS-1251) u HTML zaglavlje, redak vrste sadržaja.

    Response.CharSet code_table_name

    Mogućnosti:

    • charset_name - niz koji specificira skup znakova za ovu HTML stranicu. Naziv ove kodne tablice bit će dodan u zaglavlje HTML datoteke pod parametrom "content-type".

    Za ASP stranicu koja ne koristi svojstvo Response.Charset, parametar "content-type" u zaglavlju bit će sljedeći:

    Content-type:text/html

    Ako ASP datoteka sadrži naredbu

    tada će u zaglavlju polje tipa sadržaja izgledati ovako

    Content-type:text/html; skup znakova=Windows-1251

    Komentar:

    Ova funkcija umeće bilo koji redak u zaglavlje i ne provjerava njegovu valjanost.

    Ako stranica sadrži nekoliko oznaka Response.Charset, svaka sljedeća će vrijednost zamijeniti vlastitom.

    Svojstvo Response.ContentType

    Svojstvo ContentType omogućuje vam da odredite vrstu (tip) sadržaja HTML datoteke. Ako se ovo svojstvo ne koristi, tekst/html se uzima prema zadanim postavkama.

    Response.ContentType [=content_type]

    Mogućnosti:

    • content_type - Niz koji opisuje vrstu HTML sadržaja. Taj niz obično ima oblik "vrsta/podvrsta", gdje je vrsta glavna kategorija sadržaja, a podvrsta označava vrstu sadržaja. Za dobivanje puni popis podržane vrste - pogledajte dokumentaciju svog preglednika ili HHTP specifikaciju.

    Sljedeći primjer ilustrira postavljanje vrste sadržaja na Format definicije kanala (Push kanali).

    Drugi primjer pokazuje postavljanje svojstva na najčešće poznate vrijednosti.

    Response.Expires svojstvo

    Svojstvo Expires navodi vremensko razdoblje do HTML stranica predmemorirano od strane preglednika smatra se da nije isteklo (razdoblje pohrane). Ako korisnik od preglednika zatraži predmemoriranu stranicu koja nije istekla, preglednik je vraća izravno iz predmemorije.

    Response.Expires [=broj]

    Mogućnosti:

    • broj - Količina vremena u minutama prije nego što se stranica smatra "zakašnjelom". Postavljanje ove vrijednosti na 0 uzrokuje ova stranica odmah postaje "zakašnjelo".

    Komentar:

    Ako je ovo svojstvo postavljeno više od jednom na stranici, koristi se najmanja vrijednost.

    Svojstvo Response.ExpiresAbsolute

    Svojstvo ExpiresAbsolute navodi vrijeme i datum nakon kojeg se HTML stranica koju je preglednik predmemorirao smatra isteklom (isteklo je razdoblje zadržavanja). Ako korisnik od preglednika zatraži predmemoriranu stranicu koja nije istekla, preglednik je vraća izravno iz predmemorije. Ako je navedeno vrijeme (i datum je naveden), tada "datum isteka" ove stranice istječe u ponoć toga dana. Ako nisu navedeni ni vrijeme ni datum, tada se vrijednost dodjeljuje prema danu i vremenu kada je skripta pokrenuta.

    Response.ExpiresAbsolute [= [datum] [vrijeme]]

    Mogućnosti:

    • datum - Označava datum isteka "roka trajanja". Format datuma mora biti u skladu sa standardom RFC-1123.
    • vrijeme - Označava vrijeme kada stranica ističe. Ova vrijednost pretvara se u format GMT (srednje vrijeme po Greenwichu) prije nego što se zaglavlje pošalje klijentu.

    Komentar:

    Ako je određeno svojstvo definirano više od jednom na stranici, tada se vrijeme isteka "razdoblja pohrane" uzima kao najranije od svih navedenih vrijednosti.

    Svojstvo Response.IsClientConnected

    Ovo svojstvo je samo za čitanje, što znači da se ovom svojstvu ne mogu dodijeliti vrijednosti. Ovo svojstvo pokazuje je li klijent povezan ili više nije povezan s poslužiteljem definiranim u posljednjem Response.Write.

    Response.IsClientConnected()

    Komentar:

    Ovo svojstvo vam omogućuje da odredite kada je korisnik spojen i kada je isključen s poslužitelja. Na primjer, duljina vremenskog razdoblja između trenutka kada je poslužitelj odgovorio i kada je klijent uputio zahtjev daje sigurnost da je klijent još uvijek povezan i da ima smisla nastaviti s izvršavanjem skripte.


    Svijet besplatnih programa i korisnih savjeta
    2024 whatsappss.ru