kminek.pl

Niezamierzony efekt a la Adblock na stronie Citi Handlowy Grzegorz Wójcik

18 Jun, 2009  |  Artykuły, JavaScript

Ostatnimi czasy coraz częściej przeglądam WWW za pomocą [1] Chrome, ba – można powiedzieć nawet, że produkt Google stał się moją podstawową przeglądarką. Lubię proste i szybkie aplikacje, hołdujące idei KISS (ang. Keep It Simple, Stupid) a Chrome z pewnością się do nich zalicza.

Właśnie używając Google Chrome natrafiłem ostatnio na frapujący problem na stronie głównej banku Citi Handlowy, dostępnej pod adresem [2] www.online.citibank.pl. Otóż, w przeglądarkach opartych o silnik WebKit (czyli również w Safari) na rzeczonej stronie nie zobaczymy ani jednej reklamy (sic!). Przypomina to trochę efekt działania popularnego Adblocka i wygląda w ten sposób:

Rendering strony banku - WebKit versus pozostałe silniki

Reklam jak wiadomo nikt za bardzo nie lubi, więc ich brak można z pewnością przeżyć (chociaż nie jestem pewien, czy takie same zdanie ma również dział marketingu w Citi) – ale niepokoi również niedziałająca sekcja Aktualności (czerwona strzałka), która dla klientów ma jednak dosyć istotne znaczenie.

W trosce o user-experience wszystkich klientów banku Citi będących użytkownikami Maców (oni też mają prawo do równouprawnienia), postanowiłem charytatywnie zdiagnozować źródło powyższego problemu. Charytatywnie – bo jak wiadomo mamy kryzys finansowy i różne komórki w bankach przechodzą teraz ciężkie chwile (czytaj: restrukturyzacje) :)

Diagnoza problemu – czyli pamiętaj o konsoli błędów

W IE6 błędy JavaScript sygnalizowane są przez ikonkę, która pojawia się na dole w pasku statusu i która widoczna jest jak byk dla każdego użytkownika tej przeglądarki. W nowszych przeglądarkach (Chrome, Safari) błędy JS nie są już sygnalizowane w tak oczywisty sposób. Co nie znaczy, że nie istnieją. Trzeba się tylko do nich dokopać.

W Google Chrome konsolę JS odpalamy wciskając kombinację klawiszy Ctrl+Shift+J lub wybieramy odpowiednią pozycję z menu (Opcje strony > Dla programistów > Konsola JavaScript). Trochę trudniej jest w Safari. W menu Edycja > Preferencje na karcie Zaawansowane zaznaczamy ptaszek przy opcji Pokaż menu Programowanie w pasku menu a następnie w zmaterializowanym menu Programowanie wybieramy pozycję Pokaż konsolę błędów.

Uzbrojeni w tą tajemną wiedzę, zobaczmy co wysypuje się na stronie banku:

Raport konsoli błędów JS w Safari/Chrome

Komunikaty nie pozostawiają wątpliwości – znamy już przyczynę niedziałającej sekcji Aktualności. Pod lupę weźmy skrypt aktualnosci.js i okolicę problematycznego wiersza nr 35:

  1. if(window.ActiveXObject) {
  2. xml=new ActiveXObject("Microsoft.XMLDOM");
  3. } else if(document.implementation.createDocument) {
  4. xml=document.implementation.createDocument("", "", null);
  5. } else { }
  6.  
  7. xml.async=false;
  8. xml.load("/retail/files/citiblue/aktualnosci.xml"); //na ten wiersz narzeka WebKit
  9. items = xml.getElementsByTagName('item');

Z powyższego fragmentu kodu łatwo wywnioskować jak działa sekcja Aktualności – za pomocą JS pobierany jest plik XML (aktualnosci.xml) i na jego podstawie budowana jest tablica newsów do wyświetlenia (items). Co ciekawe – ten plik XML ma format RSS (a RSS to przecież XML), więc ukłony w stronę twórców za pomysłowe wykorzystanie RSSa jako źródła danych dla skryptu. To co może jednak dziwić to sposób pobrania tego XMLa, wykorzystujący stosunkowo mało popularny obiekt Microsoft.XMLDOM. Obiekt ten przypomina dobrze znany AJAXowy Microsoft.XmlHttp, z tym że pozwala dokonywać prostych i trochę bardziej zaawansowanych operacji na fragmentach XML – i co ciekawe – również udostępnia metodę load, za pomocą której możemy wczytać do niego łańcuch XML z pliku na serwerze. W przypadku IE obiekt jest tworzony w linii nr 2, w reszcie przeglądarek (Firefox, Opera, Safari, Chrome) obiekt tworzy linia nr 4 (metoda ta opisywana jest w [3] paru miejscach w Sieci jako zamiennik tej z IE). I tutaj zaczyna się problem. Twórca skryptu błędnie założył, że obiekt xml stworzony w IE i reszcie przeglądarek udostępnia taką samą funkcjonalność i takie same metody. Niestety – nie jest tak do końca. Otóż, o ile w Firefoxie i Operze na utworzonym obiekcie możemy wywołać metodę load (linia 8) i zadziała ona zgodnie z oczekiwaniami tak jak w IE, to jednak nie będzie to miało miejsca w przypadku przeglądarki bazującej na WebKicie.

Powyższą sytuację możemy dokładnie prześledzić na [4] tej przykładowej stronie.

Jak widać, błąd jest na tyle paskudny, że zatrzymuje wykonywanie następujących po nim instrukcji. Tłumaczy to fakt braku flashowych reklam, które umieszczane są również za pomocą JavaScript (ten sposób pozwala obejść słynny [5] problem patentowy Eolas w IE).

Rozwiązanie

Jest bardzo proste. Należy porzucić pomysł z wykorzystaniem problematycznego obiektu Microsoft.XMLDOM i oprzeć się na starym dobrym Microsoft.XmlHttp (vel XMLHttpRequest). Przecież w udostępnianej przez XHR właściwości responseXML mamy również fragment XML, który możemy parsować (np. za pomocą getElementsByTagName). Jako, że na rzeczonej stronie bankowej mamy dostęp do [6] jQuery, nie musimy się nawet bawić we własne wrappery na XHR i możemy po prostu zrobić coś takiego:

  1. $.ajax({
  2. type: "GET",
  3. url: "aktualnosci.xml",
  4. success: function(xml){
  5. items = xml.getElementsByTagName('item');
  6. }
  7. });

I oto [7] działające rozwiązanie.

Konkluzja

Przede wszystkim kłania się testowanie wyglądu i działania strony pod popularnymi przeglądarkami. Nie jest ich przecież tak dużo (wystarczy IE, Firefox, Safari/Chrome, Opera). Warto też, przed wykorzystaniem jakiegoś kawałka kodu znalezionego w Internecie, zastanowić się nad jego interakcją z pozostałymi skryptami/elementami strony. W przypadku dużych stron głównych, na których z natury rzeczy „dużo się dzieje” o takie wpadki nietrudno.

-----

Wydrukowano z: https://www.kminek.pl/niezamierzony-efekt-a-la-adblock-na-stronie-citi-handlowy/

Lista adresów URL występujących w tekście:

© 2007-2019 kminek.pl