AJAX
	
	
		- Webová interaktivní prezentace
- Klávesa "?" zobrazí krátkou nápovědu
- Tisk jako obykle
- Pro pokračování stiskněte mezerník

 
	Obsah
	
		- High-level: HTTP požadavek
- Ukázka API XMLHttpRequest
- Problematika asynchronnosti
- AJAX
- Problematika UTF-8
 
	High-level: HTTP požadavek
	
		- Všechny HTTP metody: GET, POST, HEAD, PUT, MKCOL, PROPGET, …
- Hlavičky požadavku: některé prohlížeč, některé uživatel
- Tělo požadavku: dle uživatele, UTF-8
- Hlavičky odpovědi: všechny k dispozici
- Tělo odpovědi: k dispozici jako UTF-8, v dobrých prohlížečích i bez kódování
 
	CORS: jak obejít cross-domain restriction
	
		- Požadavky do jiné domény jsou normálně zakázány
- Technika CORS povolí takový požadavek, pokud s ním vzdálený server souhlasí
- Informace o souhlasu předávány pomocí nových HTTP hlaviček
- Podporuje většina prohlížečů (kromě IE7, Opery)
 
	
Ukázka API XMLHttpRequest
	
var xhr = new XMLHttpRequest();
xhr.open("post", "/search", true); /* async */
xhr.setRequestHeader("A", "B");
xhr.send("field1=value1&field2=value2");
	
Změna stavu – callback
	
var zmenaStavu = function() {
	/* zde je mozno pracovat s odpovedi, pokud nejaka dorazila */
}
xhr.onreadystatechange = zmenaStavu;
xhr.send(...);
	
Zpracování odpovědi
	
var zmenaStavu = function() {
	/* tento callback se vola v kontextu instance XMLHttpRequestu */
	if (this.readyState != 4) { return; }
	
	if (this.status != 200) { 
		alert("HTTP/" + this.status);
		return;
	}
	
	alert(this.responseText);
}
	
	Problematika asynchronnosti
	
		- Metoda xhr.send()zpravidla neblokuje
- Jediný způsob práce s požadavkem je pomocí callbacku
- JS interpret pracuje v jednom vlákně:
xhr.onreadystatechange = function() { alert("..."); }
xhr.send();
while (1) {};
		
- Callback se vykonává v kontextu instance
- Důsledek: komplikované workaroundy
 
	
Problémy s kontextem
	Řešení #1: procpat kontext pomocí uzávěry
	
Map.prototype.search = function() {
	var self = this;
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		var response = this.responseText;
		self.showResults(response);
	}
	xhr.send();
}
	
	
Problémy s kontextem
	Řešení #2: bind
	
Map.prototype.search = function() {
	var xhr = new XMLHttpRequest();
	var response = function() {
		var response = xhr.responseText; /* kde se vzalo XHR? */
		this.showResults(response);
	}
	response = response.bind(this);
	xhr.onreadystatechange = response;
	xhr.send();
}
	
	
Problémy s kontextem
	Řešení #3: (privátní) vlasnost
	
Map.prototype.response = function() {
	var response = this._xhr.responseText;
	this.showResults(response);
}
Map.prototype.search = function() {
	this._xhr = new XMLHttpRequest();
	this._xhr.onreadystatechange = this.response.bind(this);
	this._xhr.send();
}
	
	AJAX
	
		- Za určitých podmínek je k dispozici vlastnost xhr.responseXML
- xhr.responseXML instanceof XMLDocument
- Užitečné metody pro práci se stromem (getElementsByTagName, getAttribute, …)
- Téměř identické s HTML dokumentem
- Podmínky pro vznik responseXML:
			
				- Content-type: text/xmlnebo- application/xml
- Odpověď musí být well-formed XML
- Nenumerické entity jen &,<,>,",'
- Platné kódování (pokud nespecifikováno v značce <?xml>, pak UTF-8)
 
 
	Problematika UTF-8
	
		- V JS není žádný datový typ určený pro binární data
- Lze je ukládat do pole: var binary = [192, 193];
- Lze je ukládat do řetězce: var binary = String.fromCharCode(192, 193);
- Odpověď XMLHttpRequestu je zpracovávána jako posloupnost bytů v UTF-8
- Nejbezpečnější je použít jen dolních 128 bytů (base64)
- Alternativně hodnoty > 128 zapsat v UTF-8: var response = [195, 128, 195, 129];
- Dobré prohlížeče umí na byty v odpovědi nahlížet jako na Unicode code pointy