Komunikacja JavaScript między stronami A i B

14 listopada 2011

Jak już wspominałem w innym artykule (przeczytaj komentarze, warto!), przeglądarki, ze względów bezpieczeństwa, ograniczają nasze możliwości komunikowania się między stronami w różnych domenach. Możemy natomiast dowolnie pracować i komunikować się w obrębie tej samej domeny. Jak rozszerzyć nasze możliwości?

Istnieje pewna metoda i nazywa się window.postMessage. Opracowano po prostu bezpieczną metodę komunikowania się cross-domain.

Sposób ten nie jest obsługiwany przez starsze przeglądarki (np. IE 7) dlatego powstał ciekawy plugin jQuery, który w razie czego, potrafi komunikować się w alternatywny sposób, poprzez document.location.hash. Jest także alternatywa w postaci czystego JS.

PS
Wiem, że to nie jest żadna nowość ale ostatnio mocniej zainteresowałem się tym tematem i pomyślałem, że warto o tym wspomnieć. W naszym języku ciężko natrafić nawet na wzmiankę o takich rzeczach.


Połączenie AJAX z obcą domeną za pomocą jQuery

22 października 2011

AJAX to wspaniała technologia dzięki której mogło powstać wiele rewolucyjnych usług. Ma ona jednak pewne ograniczenia związane z polityką bezpieczeństwa przeglądarek. Jednym z największych ograniczeń jest możliwość łączenia się poprzez AJAX wyłącznie ze stronami w tej samej domenie. Krótko mówiąc, nie ma możliwości pobrać strony example2.com ze strony example1.com. Tak przynajmniej myślałem do tej pory :)

Nim jeszcze przejdę do meritum sprawy, dodam, że oczywiście istnieje obejście problemu. Można napisać swego rodzaju proxy w PHP lub w innym języku i za pomocą tego proxy pobierać docelową stronę. Trzeba jednak koniecznie pamiętać aby przy tego typu rozwiązaniach jakoś filtrować kto korzysta z naszego skryptu i co pobiera. Inaczej będą problemy bo skrypt musi być przecież publicznie dostępny.

Nam jednak zależy aby całą sprawę załatwić z poziomu JavaScript. Z pomocą przychodzi YQL od Yahoo!.

Czym jest YQL? W dużym uproszczeniu, jest to język składniowo podobny do SQL, który pozwala na odczyt/manipulację różnymi zorganizowanymi strukturami danych np. HTML. Jego możliwości możemy wykorzystać dla własnych celów o czym możemy się dowiedzieć z tego artykułu. Pozwolę sobie skopiować jeden przykład:

JavaScript:
  1. $(document).ready(function(){
  2. var container = $('#target');
  3. $('.ajaxtrigger').click(function(){
  4. doAjax($(this).attr('href'));
  5. return false;
  6. });
  7. function doAjax(url){
  8. // if it is an external URI
  9. if(url.match('^http')){
  10. // call YQL
  11. $.getJSON("http://query.yahooapis.com/v1/public/yql?"+
  12. "q=select%20*%20from%20html%20where%20url%3D%22"+
  13. encodeURIComponent(url)+
  14. "%22&format=xml'&callback=?",
  15. // this function gets the data from the successful
  16. // JSON-P call
  17. function(data){
  18. // if there is data, filter it and render it out
  19. if(data.results[0]){
  20. var data = filterData(data.results[0]);
  21. container.html(data);
  22. // otherwise tell the world that something went wrong
  23. } else {
  24. var errormsg = '<p>Error: could not load the page.</p>';
  25. container.html(errormsg);
  26. }
  27. }
  28. );
  29. // if it is not an external URI, use Ajax load()
  30. } else {
  31. $('#target').load(url);
  32. }
  33. }
  34. // filter out some nasties
  35. function filterData(data){
  36. data = data.replace(/<?/body[^>]*>/g,'');
  37. data = data.replace(/[r|n]+/g,'');
  38. data = data.replace(/<--[Ss]*?-->/g,'');
  39. data = data.replace(/<noscript[^>]*>[Ss]*?</noscript>/g,'');
  40. data = data.replace(/<script[^>]*>[Ss]*?</script>/g,'');
  41. data = data.replace(/<script.*/>/,'');
  42. return data;
  43. }
  44. });

To kompleksowy kod, który pozwala stworzyć proste odnośniki na stronie służące do pobierania zewnętrznych witryn, przy okazji filtrując wyniki z potencjalnie niebezpiecznego kodu. Dobrze wiedzieć, że YQL pobiera tylko zawartość tagu body docelowej strony, co ma oczywiście swoje konsekwencje np. dostaniemy dostęp tylko do tych styli CSS, które zostały bezpośrednio "wpisane" w tagi HTML, tzw. inline CSS.

Pod tym adresem znajduje się prezentacja działania tego kodu.

Na github.com znajduje się również prosty skrypt jQuery, który szalenie upraszcza korzystanie z dobrodziejstw YQL. Dzięki niemu możemy korzystać z dotychczasowych rozwiązań opartych o AJAX i podawać zewnętrzne adresy www a skrypt sam martwi się już o to aby cały proces przebiegł bez problemów. Przykład użycia (z tej strony):

JavaScript:
  1. $('#container').load('http://google.com'); // SERIOUSLY!
  2.  
  3. $.ajax({
  4.     url: 'http://news.bbc.co.uk',
  5.     type: 'GET',
  6.     success: function(res) {
  7.         var headline = $(res.responseText).find('a.tsh').text();
  8.         alert(headline);
  9.     }
  10. });

Warto wspomnieć o alternatywnej metodzie. Istnieją rozwiązania w których JS łączy się z odpowiednim plikiem Flash i to on wykonuje za nas robotę polegającą na pobraniu zawartości strony. Ograniczeniem tej metody jest fakt, że komunikacja nie może być zablokowana na domenie docelowej w pliku crossdomain.xml. Popularnym skryptem rozwiązującym problem właśnie za pomocą Flash'a jest flXHR.

Kłopot z tzw. cross-domain AJAX jest obszerny, mam za małą wiedzę aby móc go lepiej opisać. Żywię jednak nadzieję, że tekst będzie przydanty i pomoże komuś rozwiązać jego problemy. Zachęcam do samodzielnego zgłębiania problemu i dzielenia się wiedzą w komentarzach.

PS
Pytanie za 100 punktów. Skoro AJAX nie pozwala pobierać danych z zewnętrznych adresów www to jakim cudem pozwala łączyć się z domeną http://query.yahooapis.com/ ? Pytam szczerze bo ja tego nie wiem :) Firebug nie pokazuje ruchu generowanego za pomocą tego rozwiązania jako ruch AJAX tylko przypisuje go do zakładki JS.

EDIT
Czytaj komentarze, koledzy dali tam wiele interesujących, uzupełniających informacji!


Bootstrap od Twitter

13 października 2011

Twitter wypuścił jakiś czas temu w świat całkiem ciekawy twór, który zwie się Bootstrap. Można go chyba zaliczyć do frameworków CSS chociaż korzysta też z możliwości JavaScript.

Nie zdołałem się jeszcze przekonać do takich produktów jak Blueprint (3 i pół roku temu zamieściłem nawet krótki wpis informacyjny o tym frameworku, tutaj link) czy 960 Grid System. Niby znam ich zalety ale jakoś brakuje czasu i energii żeby wreszcie któryś poznać. Chyba nie leży mi przede wszystkim idea budowania CSS na bazie siatki. Może kiedyś będzie okazja się przemóc i spróbować któregoś rozwiązania.

Bootstrap wpadł mi jednak w oko. Może dlatego, że jego dokumentacja (tak, to ten sam link co wcześniej :) ) jest tak banalna, przejrzysta i przyjazna, że każdy złapie w lot jak go używać.

Bootstrap to zbiór bibliotek CSS wzbogacony o LESS (napiszę o tym więcej, obiecuję!) i pluginy JavaScript. Razem prezentuje się to naprawdę atrakcyjnie i prosto. Wystarczy spojrzeć na przykłady z dokumentacji. Typografia, przyciski, formularze, okienka. Wszystko to i wiele więcej, gotowe do użycia, często bez naszej ingerencji, czasami wymaga tylko dodania odpowiedniej klasy do elementu.

Raczej to nie jest jeszcze ten moment gdy zbuduję pierwszą stronę w całości opartą o framework CSS jednak Bootstrap idealnie pasuje mi do tworzenia różnego rodzaju paneli administracyjnych. Z wyglądem takich paneli zawsze jest problem a tutaj mamy wszystko gotowe.

Polecam Bootstrap, warto też bliżej przyjrzeć się dostępnym pluginom JavaScript (oparte o mój ulubiony famework JS czyli jQuery) i podejrzeć trzy przykładowe strony (pierwsza, druga, trzecia).

Źródła dostępne są do ściągnięcia na GitHub pod adresem https://github.com/twitter/bootstrap.


Szachy online z otwartym źródłem

26 września 2011

Przeglądając github.com w poszukiwaniu czegoś na czym mógłbym podszkolić się z Symfony 2 natknąłem się na ciekawy projekt. Ktoś stworzył aplikację (PHP5 + JS + HTML5) do gry w szachy i udostępnił całe źródło. Co prawda wygląda na to, że sam silnik odpowiedzialny za grę nie jest napisany w PHP "ale też jest zajebiście", cytując klasyka ;)

Projekt nazywa się lichess i jest naprawdę imponujący, zwłaszcza biorąc pod uwagę, że jest prowadzony przez jedną osobę. Szczegóły techniczne:

- PHP 5.3.2, użyto frameworka Symfony 2
- JavaScript (jQuery i jQuery UI)
- HTML5 i CSS
- "mózg" gry to Crafty Chess
- pgn4web służy do podglądu gier. Daje możliwość osadzania rozgrywek na stronie www, w prostej i miłej formie miniatury, bazuje na JavaScript.

Możliwości jakie aplikacja udostępnia graczowi są co najmniej wystarczające. Możemy grać z innymi ludźmi lub z komputerem (dla komputera wybieramy jeden z ośmiu poziomów trudności). Wybieramy między grą standardową a Chess960. Decydujemy także czy gramy z zegarem.

Każda gra ma swój unikalny adres. W ten sposób rozgrywkę może śledzić więcej osób a po rozegranej grze można prześledzić wszystkie ruchy i zobaczyć cały zapis rozgrywki. Dostępny jest katalog wszystkich rozgrywanych w tej chwili i wcześniej rozegranych gier.

Dzięki zastosowaniu JS i HTML5 gra się bardzo przyjemnie, przeglądarka w żaden sposób nas nie ogranicza. Funkcji jest wiele, nie będę ich wszystkich wymieniał. Jeszcze więcej jest planów, które autor przedstawia na liście TODO.

Twórca zapowiada, że cały projekt będzie zawsze darmowy, open source a strona gdzie można wszystko wypróbować (lichess.org) będzie zawsze wolna od reklam. Kimkolwiek jest, jestem pod wrażeniem jego pracy. Na pewno prześledzę kod PHP, to jest z pewnością nieocenione źródło wiedzy podczas nauki Symfony 2.


Pokochać JavaScript

25 stycznia 2010

Stało się i nie ma już odwrotu. Trzeba nauczyć się JavaScript. Nie, nie mówię o sobie bo ja już go znam (na jakimś tam akceptowalnym poziomie :) ). Mówię do Ciebie.

Nie pamiętam kiedy pierwszy raz zetknąłem się z JavaScript ale wiem na co wtedy była moda. Implementacja tego języka w wielu przeglądarkach kulała a jeżeli nawet coś bardziej złożonego działało to w każdej przeglądarce trzeba było to napisać trochę inaczej. Z tego powodu nie było wielu zaawansowanych koderów JS a w sieci krążyły różne skrypciki, które webmasterzy dzisiaj zgodnie określają mianem wodotrysków. Implementacja zegarka albo kalkulatora, "padający śnieg" czy animowany tekst podążający za kursorem myszki - oto na co było stać większość programistów JS i czym zachwycali się twórcy stron www.

Wreszcie przyszło jednak opamiętanie i wszystkie straszydła zaczęły znikać z sieci. Bo na cholerę komuś zegarek na stronie skoro każdy ma go w prawym dolnym rogu... ?

Nadeszły gorsze czasy dla JS... co wyszło temu językowi tylko na dobre :) Na całe szczęście język nadal się rozwijał a producenci przeglądarek nie zapomnieli o nim i pomału programowanie ze znośnego stawało się przyjemne. Co mądrzejsi zaczęli się zastanawiać jak wykorzystać potencjał, niemały potencjał należy dodać, tego języka. Po cichu zaczęły się pojawiać jakieś bardziej ambitne próby stworzenia czegoś praktycznego w JavaScript.

Może i Google Maps nie przyniosłoby ze sobą otrzeźwienia (mimo zaawansowanego użycia JS) gdyby nie to, że wykorzystano obiekt XMLHttpRequest (wymyślony przez Microsoft) dzięki któremu od tamtej chwili webmasterzy na całym świecie mogą się cieszyć technologią znaną pod nazwą AJAX.

I zaczęło się :) Wchodzisz sobie na stronę, klikasz, coś się dzieje, ewidentnie pobierane są nowe informacje z serwera a strona się nie przeładowała... To była rewolucja, technika ta szybko stała się pragnieniem każdego właściciela www. JavaScript nareszcie został doceniony, to były jego drugie narodziny. Szczęśliwie zbiegło się to w czasie z już całkiem przyzwoitymi implementacjami JS w przeglądarkach.

Dalej opowiadać chyba już nie trzeba, gdyby nie powyżej opisane wydarzenia to Internet z pewnością wyglądałby dzisiaj i działał zdecydowanie gorzej. Właściwie to nawet może nie mielibyśmy dzisiaj Web 2.0? Kto wie, w końcu JS i AJAX miały w tym trendzie bardzo duży udział a nowe możliwości były inspiracją dla pierwszych pionierów.

Dzisiaj programowanie w JS to zupełnie inna bajka niż wtedy gdy pierwszy raz się nim zainteresowałem. Twórcy przeglądarek prześcigają się w implementacji ekstremalnie szybkich silników JavaScript, mamy do wyboru wiele frameworków i bibliotek ułatwiających życie webmasterom a Google jasno daje do zrozumienia swoimi rozwiązaniami (Gmail, Google Maps, Google Docs etc. oraz cała idea Chromium OS), że bez JS już się nie da...

Zachęcam wszystkich do poznawania możliwości JS. Zapewniam Cię, że jeżeli wiążesz swoją przyszłość z tworzeniem stron www to nie masz wyjścia ;)

Na nasze szczęście istnieją takie projekty jak jQuery, dzięki któremu programowanie w JS to poezja. Wybór frameworka należy do Ciebie ale podpowiem Ci, że ja już nie zabieram się za żaden projekt bez jQuery :) Oczywiście czasami coś prostego lepiej zaprogramować w czystym JS niż ładować dużą bibliotekę tylko po to aby obsłużyć jeden przycisk. Pamiętaj o tym.

Jeżeli na początku Twojej przygody brakuje Ci wielu rozwiązań z PHP to polecam zainteresować się projektem php.js. Nie radzę dodawać tej biblioteki do swoich stron (chociażby z powodu jej rozmiarów) ale łatwiej będzie Ci się czegoś nauczyć gdy zobaczysz jak zaimplementowane są w JS funkcje z dobrze znanego Ci języka.

Jest też coś dla programistów Java. Napisz wszystko w Javie i użyj Google Web Toolkit a kompilator sam zbuduje całą aplikację łącznie ze skryptami JS. Chociaż nie wszyscy są zdania, że to dobre rozwiązanie...

Podsumowując, chociażbyś bardzo chciał to JavaScript nie unikniesz. Ale nie ma ku temu powodów, czasy się zmieniły zdecydowanie na korzyść tego języka. Zacznij go odkrywać a zobaczysz ile nowych możliwości otworzy się przed Tobą i jak łatwo uzyskać niektóre efekty (zwłaszcza z pomocą narzędzi typu jQuery :) ).