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 */, '*');
         }
     });
    


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow