Same-origin policy & Cross-Origin Resource Sharing

Korzystając z różnych API przy pomocy AJAX-a być może napotkałeś na problem z polityką same-origin (SOP) lub CORS. Uwidacznia się ona przez wyświetlenie błędu w konsoli, który brzmi mniej więcej tak: XMLHttpRequest cannot load (…). No ‚Access-Control-Allow-Origin’ header is present on the requested resource (…). 

Same-origin policy (SOP)

Ograniczenie, o którym wspomniałem zostało wprowadzone z powodów bezpieczeństwa, aby nie móc wysyłać/pobierać danych poprzez AJAX, których adresy URL [tj. adres żądania (request)  np. http://www.bogolubow.com:80/ oraz odpowiedzi (response) np. https://maps.googleapis.com:8080/maps/api] miały ten sam:

  • protokół (http/https),
  • host (www.bogolubow.com/maps.googleapis.com)
  • port (80/8080).

Jeśli, któryś z tych elementów się nie będzie zgadzać to w konsoli pojawi się błąd. Dla jasności w przykładzie wyżej żaden z elementów się nie zgadza (nie jest identyczny, a wszystkie powinny) więc AJAX zwróci nam błąd.

Jeśli mielibyśmy zdefiniować ogólną definicję tej zasady (a nie konkretny przypadek użycia jak w przykładzie wyżej) to mogłaby by ona brzmieć mniej więcej tak:  dwa konteksty mogą modyfikować DOM tylko wtedy, gdy oba mają takie same pochodzenie (ang. origin).

Cross-Origin Resource Sharing (CORS)

CORS to technologia umożliwiająca wykonywanie asynchronicznych połączeń do każdego adresu URL, o ile ten adres na to zezwoli. Można uznać, że jest to  rozszerzenie polityki same-origin i bardzo dobrze ponieważ często potrzebowaliśmy się komunikować z zewnętrzni zasobami co było bardzo utrudnione (o zapytaniach JSONP, jeszcze kiedyś napiszę).

Nagłówek Access-Control-Allow-Origin

Jak już wspomniałem wcześniej zewnętrzny zasób musi pozwolić na odbiór danych i dzieje się to przez zdefiniowanie odpowiedniego nagłówka, który powinien wyglądać w taki sposób:

Access-Control-Allow-Origin: [url]

Gdzie [url] to adres, z którego serwer zezwala na pobranie danych. Możemy również użyć gwiazdki (*), jednak z powodów bezpieczeństwa nie jest to polecane rozwiązanie.

Załóżmy, że nasz zewnętrzny zasób to http://www.webperfection.pl/api.php, teraz chcielibyśmy w lokalizacji http://www.bogolubow.com/ajax.js pobrać dane za pomocą AJAX-a. W pliku api.php musimy ustawić wstawić powyższy kod:

header('Access-Control-Allow-Origin: http://www.bogolubow.com');

To wystarczy, aby już nasze API udostępniało zasoby dla hosta: www.bogolubow.com z odpowiednim protokołem (http) i domyślnym portem (80).

Przeglądarki i protokół file://

Należy pamiętać, że to po stronie przeglądarki zależy implementacja SOP i CORS dlatego efekty działania mogą być różne. Aby sprawdzić jakie przeglądarki wspierają to rozwiązanie wystarczy skorzystać z caniuse.com.

Częstym problemem jest samo uruchomienie pliku html z podłączonym AJAX-em na lokalnym dysku, co często powoduje pojawienie się błędu SOP/CORS nawet jeśli oba elementy znajdują się na naszym dysku. Wtedy trzeba po prostu uruchomić plik przez serwer  zainstalowany w systemie (np. apache -> XAMPP + localhost).

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

*

*

one × 2 =