Bardzo często tworzymy osobne usługi, które dostarczają jakieś dane. Pisząc aplikacje ASP.NET Web nierzadko chcemy korzystać z zewnętrznych usług, zamiast hostować dane w tym samym projekcie. Niestety może to spowodować problemy, jeśli chcemy skonsumować usługę w JavaScript, a należy ona do innej domeny.
Załóżmy, że mamy jakąś usługę REST. Dla testów posłużyłem się http://www.mocky.io. Polecam tą stronę, można generować tam własne “mocki”. Dla tego wpisu stworzyłem mock, który zwraca następującą treść np.:
Następnie na stronie, mam następujący kod JavaScript, który po prostu próbuje połączyć się z usługą i odczytać dane:
Szybko przekonamy się, że wykonanie zakończy się błędem:
Przeglądarka zawsze blokuje wywołania Ajax, które próbują wywołać usługę z innej domeny (w tym przypadku localhost –> mocky.io).
Jeśli usługa zwraca dane JSON, jednym z rozwiązań może być JSONP, czyli “JavaScript Object Notation with Padding”.
Rozwiązanie wykorzystuje lukę w przeglądarkach i jest bardzo często stosowane. JSON jak wiemy, może stanowić poprawny kod JavaScript. Przeglądarki nie dopuszczają wywołań do innych domen, ale dozwolone jest załadowanie kodu, które znajduje się w innej domenie, np. poprzez <script src=’adres do zewnetrznej domeny’./>. Z tego względu, jeśli potraktujemy zawartość zwróconą przez naszą usługę jako kod, wtedy będziemy w stanie połączyć się z nią.
Wyobraźmy sobie, że usługa zamiast zwracać {“Text”:”Hello world”}, zwraca callback({“Text:”HelloWorld”}). Dla przeglądarki jest to jak najbardziej poprawny kod i można go wykonać.
Technika jest na tyle popularna, że istnieje wiele narzędzi, które wspierają ją. Na przykład, dla powyższego wywołania ajaxowego możemy:
Wystarczy dodać dataType:’jsonp’ i zobaczymy na ekranie załadowany tekst. Warto przeanalizować, jakie zapytanie jest wysłane oraz jaka odpowiedź konkretnie przychodzi. Zaglądać do logów zobaczymy, że wysyłamy:
“http://www.mocky.io/v2/55772bf754441acd1b6697d0?callback=jQuery110208627150375396013_1433874507041&_=1433874507042”.
Nie trudno spostrzec, że został dodany parametr callback, wraz z nazwą funkcji. Usługa (w tym przypadku mocky.io) rozpozna parametr callback i zwróci odpowiedź w postaci:
jQuery110208627150375396013_1433874507041({“Text”:”Hello world!”});
Następnie jQuery wykona daną funkcję, która tak naprawdę odczyta parametr wejściowy i przekaże ją do funkcji done. Innymi słowy, kod zwrócony przez usługę zostanie wykonany w formie funkcji callback’a, który wywołuje “done” przekazując dostarczony parametr, który stanowi dane zwrócone przez usługę.
Warto zwrócić uwagę, że usługa musi rozpoznawać parametr callback i zwracać zawartość w formie callback(dane) zamiast po prostu czyste dane. Domyślnie WebAPI nie zrobi tego za nas, ale w przyszłym wpisie pokażę w jaki sposób to osigągnąć. Czyste dane JSON zwracane przez usługi, stanowią poprawny kod JavaScript, ale nic z nimi nie możemy zrobić. Jeśli opleciemy je w funkcję, umożliwi nam to przechwycenie tych danych poprzez implementację danej funkcji i odczytanie parametrów wejściowych.
“połączyć się z nją” – maly blad 🙂
Haha troche mi wstyd, dzieki:)
Super wpis, tego właśnie szukałem
dobre