Szukaj…
Wprowadzenie
Zasady tego samego pochodzenia są używane przez przeglądarki internetowe, aby uniemożliwić skryptom dostęp do zdalnej treści, jeśli zdalny adres nie ma tego samego pochodzenia . Zapobiega to wykonywaniu przez złośliwe skrypty żądań do innych witryn w celu uzyskania poufnych danych.
Pochodzenie dwóch adresów jest uważane za takie samo, jeśli oba adresy URL mają ten sam protokół , nazwę hosta i port .
Sposoby obchodzenia zasad tego samego pochodzenia
Jeśli chodzi o silniki JavaScript po stronie klienta (te działające w przeglądarce), nie ma prostego rozwiązania do żądania treści ze źródeł innych niż bieżąca domena. (Nawiasem mówiąc, to ograniczenie nie istnieje w narzędziach serwera JavaScript, takich jak Node JS.)
Jednak (w niektórych sytuacjach) rzeczywiście jest możliwe pobieranie danych z innych źródeł przy użyciu następujących metod. Należy pamiętać, że niektóre z nich mogą przedstawiać hacki lub obejścia zamiast rozwiązań, na których powinien polegać system produkcji.
Metoda 1: CORS
Obecnie większość publicznych interfejsów API pozwala programistom wysyłać dane dwukierunkowo między klientem a serwerem, włączając funkcję CORS (Cross-Origin Resource Sharing). Przeglądarka sprawdzi, czy ustawiony jest określony nagłówek HTTP ( Access-Control-Allow-Origin
) i czy domena strony żądającej jest wymieniona w wartości nagłówka. Jeśli tak, przeglądarka pozwoli na ustanowienie połączeń AJAX.
Ponieważ jednak programiści nie mogą zmieniać nagłówków odpowiedzi innych serwerów, nie zawsze można polegać na tej metodzie.
Metoda 2: JSONP
JSON z dodawaniem P jest powszechnie obwiniany za obejście problemu. Nie jest to najprostsza metoda, ale nadal wykonuje zadanie. Ta metoda wykorzystuje fakt, że pliki skryptów można ładować z dowolnej domeny. Należy jednak wspomnieć, że żądanie kodu JavaScript ze źródeł zewnętrznych zawsze stanowi potencjalne zagrożenie bezpieczeństwa i należy tego zasadniczo unikać, jeśli dostępne jest lepsze rozwiązanie.
Dane żądane przy użyciu JSONP to zazwyczaj JSON , który pasuje do składni używanej do definicji obiektów w JavaScript, dzięki czemu ta metoda transportu jest bardzo prosta. Częstym sposobem pozwalania stronom internetowym na korzystanie z danych zewnętrznych uzyskanych za pomocą JSONP jest zawijanie ich w funkcji wywołania zwrotnego, która jest ustawiana za pomocą parametru GET
w adresie URL. Po załadowaniu zewnętrznego pliku skryptu funkcja zostanie wywołana z danymi jako pierwszym parametrem.
<script>
function myfunc(obj){
console.log(obj.example_field);
}
</script>
<script src="http://example.com/api/endpoint.js?callback=myfunc"></script>
Zawartość http://example.com/api/endpoint.js?callback=myfunc
może wyglądać następująco:
myfunc({"example_field":true})
Funkcja zawsze musi być zdefiniowana jako pierwsza, w przeciwnym razie nie zostanie zdefiniowana, gdy zostanie załadowany zewnętrzny skrypt.
Bezpieczna komunikacja między źródłami z wiadomościami
Metodę window.postMessage()
wraz z relatywnym window.onmessage
obsługi zdarzeń window.onmessage
można bezpiecznie wykorzystać do umożliwienia komunikacji między źródłami.
Metodę postMessage()
window
docelowego można wywołać, aby wysłać wiadomość do innego window
, które będzie w stanie przechwycić ją za pomocą onmessage
obsługi zdarzeń onmessage
, opracować ją i, jeśli to konieczne, wysłać odpowiedź z powrotem do okna nadawcy za pomocą postMessage()
ponownie.
Przykład okna komunikującego się z ramką podrzędną
Treść strony
http://main-site.com/index.html
:<!-- ... --> <iframe id="frame-id" src="http://other-site.com/index.html"></iframe> <script src="main_site_script.js"></script> <!-- ... -->
Treść
http://other-site.com/index.html
:<!-- ... --> <script src="other_site_script.js"></src> <!-- ... -->
Treść
main_site_script.js
:// Get the <iframe>'s window var frameWindow = document.getElementById('frame-id').contentWindow; // Add a listener for a response window.addEventListener('message', function(evt) { // IMPORTANT: Check the origin of the data! if (event.origin.indexOf('http://other-site.com') == 0) { // Check the response console.log(evt.data); /* ... */ } }); // Send a message to the frame's window frameWindow.postMessage(/* any obj or var */, '*');
Zawartość
other_site_script.js
:window.addEventListener('message', function(evt) { // IMPORTANT: Check the origin of the data! if (event.origin.indexOf('http://main-site.com') == 0) { // Read and elaborate the received data console.log(evt.data); /* ... */ // Send a response back to the main window window.parent.postMessage(/* any obj or var */, '*'); } });