Polityka tego samego pochodzenia
Nie możesz uzyskać dostępu do <iframe>
innego pochodzenia za pomocą JavaScript, byłoby to ogromną wadą bezpieczeństwa, gdybyś mógł to zrobić. W przypadku przeglądarek zasad tego samego pochodzenia skrypty blokują próby uzyskania dostępu do ramki o innym pochodzeniu .
Pochodzenie uważa się za różne, jeśli nie zachowano co najmniej jednej z następujących części adresu:
<protocol>://<hostname>:<port>/...
Protokół , nazwa hosta i port muszą być takie same jak w domenie, jeśli chcesz uzyskać dostęp do ramki.
UWAGA: wiadomo, że Internet Explorer nie ściśle przestrzega tej zasady, zobacz tutaj, aby uzyskać szczegółowe informacje.
Przykłady
Oto, co by się stało, próbując uzyskać dostęp do następujących adresów URL z http://www.example.com/home/index.html
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html:80 -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname
Obejście
Mimo że zasady tego samego pochodzenia blokują skryptom dostęp do zawartości witryn o innym pochodzeniu, jeśli jesteś właścicielem obu stron, możesz obejść ten problem, używając window.postMessage
i jego względnego message
zdarzenia do wysyłania wiadomości między dwiema stronami, w następujący sposób:
Na twojej stronie głównej:
let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
Drugim argumentem postMessage()
może być '*'
wskazanie braku preferencji co do pochodzenia miejsca docelowego. W miarę możliwości zawsze należy podać miejsce docelowe, aby uniknąć ujawnienia danych wysyłanych do innych witryn.
W twoim <iframe>
(zawartym na stronie głównej):
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://your-first-site.com')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
Metodę tę można zastosować w obu kierunkach , tworząc odbiornik również na stronie głównej i odbierając odpowiedzi z ramki. Ta sama logika może być również zaimplementowana w wyskakujących oknach i zasadniczo w każdym nowym oknie generowanym również przez stronę główną (np. Przy użyciu window.open()
), bez różnicy.
Wyłączenie polityki tego samego pochodzenia w Twojej przeglądarce
Jest już kilka dobrych odpowiedzi na ten temat (właśnie znalazłem googlujących się w Google), więc dla przeglądarek, w których jest to możliwe, połączę odpowiedź względną. Pamiętaj jednak, że wyłączenie zasad tego samego pochodzenia wpłynie tylko na Twoją przeglądarkę . Ponadto uruchomienie przeglądarki z wyłączonymi ustawieniami zabezpieczeń tego samego pochodzenia zapewnia każdemu dostęp do strony internetowej do zasobów pochodzących z różnych źródeł, więc jest to bardzo niebezpieczne i NIGDY nie powinno być wykonywane, jeśli nie wiesz dokładnie, co robisz (np. W celach programistycznych) .
Access-Control-Allow-Origin
nie dotyczy iFrames, tylko XHR, czcionek, WebGL icanvas.drawImage
. Wierzę, żepostMessage
to jedyna opcja.