Přidat článek mezi oblíbenéZasílat nové komentáře e-mailem Ajax - IFrame

Registrovaný los Moderátor, , Programování, 2 komentáře (8550 zobrazení)

Keď už vieme prenášať požiadavky prostredníctvom objektu XMLHttpRequest, nezaškodí poznať aj iné alternatívy komunikácie medzi klientom a serverom. V dnešnom článku sa podrobne pozrieme na prenos údajov cez dynamicky vytvorený skrytý rámec.

Minule sme sa oboznámili s použitím objektu

XMLHttpRequest

, ktorý je určený na komunikáciu klienta so serverom. Dnešný článok bude o alternatívnom spôsobe komunikácie, ktorého použitie je v niektorých aspektoch oveľa výhodnejšie. Ak potrebujeme odosielať iba požiadavky typu GET a POST (čo je drvivá väčšina prípadov), je v súčasnosti komunikácia prostredníctvom skrytého rámca väčšinou tou lepšou možnosťou, ako samotný objekt

XMLHttpRequest

.

Prostredníctvom elementu

iframe

dokážeme prenášať údaje v HTML alebo v textovom formáte. Navyše od objektu

XMLHttpRequest

môžeme prenášať aj súbory z klientského počítača. Cestu k súboru však musí najskôr návštevník stránky vybrať, až potom môžeme prepísaním atribútu

target

formulára presmerovať požiadavku do skrytého rámca a súbor pomocou JavaScriptu odoslať na server.

V súčasnosti najväčšou výhodou prenosu dát prostredníctvom skrytého rámca je to, že v prehliadači Internet Explorer 6 a jeho predchádzajúcich verziách nepotrebujme používať ActiveX objekt. Pri vyššom stupni zabezpečenia tak nebude vyskakovať na používateľa otravná hláška. Okrem toho je element

iframe

podporovaný vo viacerých prehliadačoch, než objekt

XMLHttpRequest

. Vývoj však nezastavíme a v budúcnosti zrejme nebudú tieto dve výhody skrytého rámca až také podstatné.

Podobne ako to bolo pri použití objektu

XMLHttpRequest

, ani prostredníctvom rámca nemôžeme plne komunikovať so serverom z inej domény. Odosielanie požiadaviek je síce možné, avšak prečítanie odpovede už také jednoduché nie je. V JavaScripte sa totiž nedostaneme k dokumentu v elemente

iframe

, ktorý obsahuje stránku servera z inej domény. Napriek tomu môžeme v obmedzenej forme dostať odpoveď aj z takéhoto servera. Odpoveď môže byť obsiahnutá v adrese stránky, na ktorú server požiadavku skriptu presmeruje. Prečítaním adresy rámca z atribútu

src

sa túto odpoveď dozvieme.

Vytvorenie skrytého rámca

Najjednoduchším spôsobom, ako vytvoriť na stránke skrytý element

iframe

, je vložiť ho priamo do HTML kódu stránky. To však vôbec nie je elegantné. Keďže chceme oddeliť správanie od obsahu stránky, budeme skrytý rámec vytvárať prostredníctvom JavaScriptu. Rámec vytvoríme pomocou štandardnej metódy

createElement

pre vytváranie elementov. Aby bol neviditeľný, nastavíme mu nulovú šírku, výšku a nulové okraje. Posledným krokom je nastavenie obslužnej funkcie, ktorá sa zavolá vždy po dokončení nahrávania obsahu rámca.

function createIFrame ()
{
	var iframe = null;
	
	if (document.createElement)
	{
		var iframe = document.createElement ("iframe");

		iframe.style.position = "absolute";
		iframe.style.border = "0";
		iframe.style.width = "0";
		iframe.style.height = "0";
		iframe.load = function () {receiveResponse (iframe)};
		
		document.body.appendChild (iframe);

		if (iframe.addEventListener) // Gecko / W3C
			iframe.addEventListener ("load", iframe.load, false);
		else if (iframe.attachEvent) // IE
			iframe.attachEvent ("onload", iframe.load);
		else
			iframe.onload = iframe.load;
	}
	
	return iframe;
}

Pre nastavenie obslužnej funkcie použijeme štandardnú metódu

addEventListener

. V prehliadačoch, ktoré túto metódu nepodporujú, skúsime použiť neštandardnú metódu

attachEvent

, prípadne priradiť obslužnú funkciu priamo. Podobne ako v predchádzajúcom článku musíme aj tu myslieť na uvoľňovanie pamäte. Keďže sme elementu

iframe

nastavili obslužnú funkciu, ktorá používa odkaz na

iframe

, vytvorili sme kruhovú referenciu medzi elementom dokumentu a objektom JavaScriptu. Aby sme dokázali neskôr tento začarovaný kruh rozťať, odložíme si dočasne odkaz na obslužnú funkciu do vlastnosti

load

elementu

iframe

.

Odoslanie požiadavky

Požiadavku na server odošle prehliadač automaticky po nastavení adresy skrytého rámca alebo po zavolaní metódy

submit

formulára, ktorého odpoveď smeruje do skrytého rámca. Po spracovaní požiadavky sa odpoveď servera v tomto rámci objaví.

Odoslanie požiadavky metódou POST

Odoslanie údajov z formulára, ktorý je už na stránke, je jednoduché. Rámcu, ktorý sme vytvorili, priradíme nejaké meno v atribúte

name

a to isté meno nastavíme formuláru do atribútu

target

. Väčšinou však takýto formulár na stránke nemáme a odoslanie bude zložitejšie.

Pri odosielaní údajov metódou POST vytvoríme v skrytom rámci formulár, ktorý naplníme požadovanými údajmi. Nakoniec ho odošleme metódou

submit

. Odoslanú požiadavku zakóduje samotný prehliadač, takže nemáme priamu kontrolu nad odoslanými údajmi.

function sendRequest (data, url)
{
	var iframe = createIFrame ();
	
	if (iframe)
	{
		var iframeDoc = (iframe.contentWindow?
			iframe.contentWindow.document:
			iframe.contentDocument);

		if (iframeDoc)
		{
			var pairs = data.split ("&");
			var inputs = [];
			var encode = function (text)
			{
				return decodeURIComponent (text).
					replace (/&/g, "&").
					replace (/</g, "&lt;").
					replace (/>/g, "&gt;").
					replace (/"/g, "&quot;");
			};

			for (var i = 0; i < pairs.length; ++i)
			{
				var pair = pairs [i].split ("=");

				inputs [i] =
					'<input type="text" name="' + encode (pair [0]) + '"' +
					' value="' + encode (pair [1]) + '" />';
			}
			
			iframeDoc.open ();

			iframeDoc.write (
				'<form action="' + url + '" method="POST">' +
				inputs.join ("") +
				"</form>");

			iframeDoc.getElementsByTagName ("form") [0].submit ();
		}

		return iframeDoc;
	}

	return false;
}

Uvedená funkcia dynamicky vytvorí skrytý rámec. Aby bolo možné zapísať do dokumentu rámca formulár, musí sa najprv dostať k dokumentu rámca, ktorý si uloží do premennej

iframeDoc

. V nasledujúcom kroku vygeneruje formulár na základe údajov, ktoré chceme odoslať. Tieto údaje sú uložené v reťazci

data

. Namiesto reťazca by sme mohli použiť napríklad asociatívne pole. Reťazec používame preto, aby bolo rozhranie funkcie pre odoslanie požiadavky rovnaké, ako v minulom článku.

Premenná

data

teda obsahuje zakódovaný formulár. Formulár je zakódovaný rovako, ako by to spravil pri odosielaní prehliadač. Reťazec pozostáva z dvojíc

meno=hodnota

, ktoré sú zreťazené znakom

&

. Meno aj hodnota sú URL-zakódované. Funkcia pre odoslanie požiadavky metódou POST tento reťazec dekóduje a vytvorí z neho formulár. Každá dvojica

meno=hodnota

zodpovedá jednému elementu

input type=text

, ktorého atribút

name

obsahuje meno a atribút

value

obsahuje hodnotu. Vygenerovaný formulár odošle údaje na zadanú adresu, čo dosiahneme nastavením atribútu

action

. Nakoniec volaním metódy

submit

formulár odošleme.

Odoslanie požiadavky metódou GET

Odoslanie požiadavky metódou GET je oveľa jednoduchšie. Stačí nastaviť zdroj rámca prostredníctvom atribútu

src

na požadovanú URL.

function sendRequest (data, url)
{
	var iframe = createIFrame ();
	
	if (iframe)
		iframe.location.replace (url);
}

Táto funkcia ani nepotrebuje komentár. Nasledujúcim krokom bude prijatie a spracovanie odpovede nastavenou funkciou

receiveResponse

.

Prijatie odpovede

Pri vytváraní rámca sme mu nastavili obslužnú funkciu, ktorá sa zavolá po nahraní jeho obsahu. Táto funkcia spracuje odpoveď nastavenú v jeho dokumente:

function receiveResponse (iframe)
{
	var iframeDoc = (iframe.contentWindow?
		iframe.contentWindow.document:
		iframe.contentDocument);
	
	var text = iframeDoc.body.innerHTML.
		replace (/&amp;/g, "&").
		replace (/&lt;/g, "<").
		replace (/&gt;/g, ">").
		replace (/&quot;/g, '"');

	alert (text);

	if (iframe.removeEventListener)
		iframe.removeEventListener ("load", iframe.load, false);
	else if (iframe.detachEvent)
		iframe.detachEvent ("onload", iframe.load);
	else
		iframe.onload = null;
	
	iframe.load = null;
	setTimeout (function () {document.body.removeChild (iframe)}, 0);
}

Pri prijatí odpovede sa najprv dostaneme k dokumentu rámca. Potom dekódujeme jeho obsah. Ten je zakódovaný do HTML, takže musíme nahradiť špeciálne entity za znaky, ktoré reprezentujú.

Po spracovaní odpovede nesmieme zabudnúť na odregistrovanie obslužnej funkcie a odstránenie skrytého rámca zo stránky. Odstránením obslužnej funkcie, na ktorú sme si odložili referenciu do vlastnosti

load

, prerušíme kruhovú referenciu, čím umožníme prehliadaču Internet Explorer uvoľniť pamäť. Odstránenie skrytého rámca zo stránky o niečo oneskoríme, pretože odstraňujeme element, ktorého udalosť práve obsluhujeme. V opačnom prípade by prehliadač Firefox neukončil korektne načítavanie obsahu rámca.

Záver

V tejto časti seriálu sme si ukázali spôsob odosielania údajov metódou GET aj POST prostredníctvom skrytého rámca. Uvedené funkcie by mali stačiť na vytvorenie jednoduchej aplikácie, kde komunikuje klient so serverom.

Podobne ako v predchádzajúcom článku sme sa aj tu zaoberali uvoľňovaním pamäte. Pri písaní funkcií v JavaScripte, ktoré plánujeme využívať mnohokrát za sebou, by sme sa mali vždy zamyslieť aj nad problémom neuvoľňovania pamäte v niektorých prehliadačoch.

Předmět Autor Datum
Vynikajúci serál, len tak ďalej. Niečo také na slovensko - českom internete dlho chýbalo. škoda že v…
Zp 09.11.2006 00:52
Zp
Už se těším až budu mít čas a vyzkouším si to. poslední
Squad_leader 11.11.2006 12:19
Squad_leader

Vynikajúci serál, len tak ďalej. Niečo také na slovensko - českom internete dlho chýbalo. škoda že v čase keď som ja začínal s ajaxom toho bolo na nete oveľa menej. Inak Rich Internet Applications sa dajú kódiť aj vo Flashi.

Zpět na články Přidat komentář k článku