Technologia AJAX pozwoliła twórcom witryn na łączenie się z serwerem i pobieranie z niego potrzebnych informacji bez przeładowywania całej strony. Nowe możliwości stały się jednocześnie furtką dla nowego rodzaju ataków na strony, poprzez wysyłanie lub pobieranie danych z innych, niż aktualnie odwiedzana witryn. Mogło się to dziać w tle bez wiedzy użytkownika. Taka opcja została więc szybko zablokowana przez twórców przeglądarek. Co jednak, gdy mimo wszystko zajdzie potrzeba połączenia się z serwerem o innym adresie?
Cross-domain
W przypadku innego typu danych jak np. obrazków, czy całych skryptów ten problem nie występuje. Wystarczy wpisać dowolny adres w atrybucie src, a przeglądarka posłusznie zaciągnie wskazany obiekt. Dlaczego, więc nie wykorzystać tej metody do asynchronicznego kontaktu z serwerem?
<script type="text/javascript" src="http://www.matw.pl/samples/codeigniter/static/js/jquery-1.8.3.min.js"></script>
Tworząc za pomocą języka JavaScript odpowiedni adres możemy umieścić w nim praktycznie dowolne parametry. Następnie wystarczy dodać odpowiednio przygotowany fragment kodu do dokumentu, wtedy przeglądarka pobierze dane z wskazanej lokalizacji, a my będziemy mogli je dalej przetworzyć. Tak, w dużym skrócie, działa skrypt pozwalający na takie połączenie. To podejście ma jednak pewne wady m.in. brak możliwości ustawienia nagłówków czy konieczność przekazywania danych metodą GET, co jednak w większości przypadków nie będzie stanowiło znaczących trudności.
Przykład
Powyższe rozwiązanie zostało również zaimplementowane w bibliotece jQuery. Przejdźmy zatem do krótkiego przykładu obrazującego jego działanie. Nasz skrypt ma za zadanie wysłać do serwera dwa wyrazy uzupełnione w formularzu, dla których serwer zwróci odległość pomiędzy nimi. Odległość wyrazów jest równa liczbie operacji (dodanie znaku, usunięcie znaku lub zmiana wskazanego znaku na inny), które należy wykonać, aby z jednego wyrazu otrzymać drugi np. odległość wyrazów hotel i hottel wynosi 1, ponieważ, aby z pierwszego z nich uzyskać drugi należy w odpowiednim miejscu dodać literkę t (lub analogicznie z drugiego ją usunąć). Do wyznaczenia odległości skorzystamy z natywnej funkcji PHP levenshtein. Funkcja napisana w JavaScript z pomocą biblioteki jQuery wygląda następująco:
<script type="text/javascript"> function ajax_check_word_distance() { var url = 'http://www.matw.pl/samples/crossdomainajax/index.php'; var word1 = $('#word1').val(); var word2 = $('#word2').val(); $.ajax({ url: url, dataType: 'jsonp', type: 'GET', data: { word1: word1, word2: word2 }, success: function(response) { console.log(response); $('#info').html('Odległość wyrazów "'+word1+'" i "'+word2+'" wynosi '+response); } }); } </script>
Parametrem odpowiadającym za możliwość połączenia z inną domeną jest ustawienie dataType na JSONP – który w obsłudze jest analogiczny do tradycyjnego JSON’a . Różnica w zapytaniu polega na przesłaniu specjalnego identyfikatora, który automatycznie jest doklejany przez bibliotekę a później dodaniu go do zwracanej z serwera odpowiedzi. W przypadku cross-domain’owego połączenia na próżno możemy szukać w konsoli zapytania przesyłanego AJAX’em – inny sposób jego wykonania sprawia, że jest ono tam niewidoczne, a podglądnięcie go wymaga zastosowania programów takich jak np. Fiddler. Skrypt na serwerze przedstawia się następująco:
<?php //odbieramy przesłane słowa $word1 = $_GET['word1']; $word2 = $_GET['word2']; //wyznaczamy ich odległość $distance = levenshtein($word1,$word2); //wysyłamy odpowiedź jako JSON die($_GET['callback'].'('.json_encode($distance).')'); ?>
A teraz zapraszam do przetestowania opisanego przykładu:
Wyraz 1:
Wyraz 2:
Zobacz także: