방법은 다음과 같습니다.
주어진 슈퍼 도메인 (예 : example.com)의 하위 도메인 간 공유를 위해 해당 상황에서 사용할 수있는 기술이 있습니다. 에 적용 할 수있는 localStorage
, IndexedDB
, SharedWorker
, BroadcastChannel
, 등, 동일 원본 페이지 간의 공유 기능을 제공하지만, 어떤 이유에 대한 수정 존중하지 않는 모두가 document.domain
그들을 직접 원점으로 상위 도메인을 사용할 수 있도록 것이라고합니다.
(1) 데이터가 속할 하나의 "기본"도메인을 선택합니다. 즉, https://example.com 또는 https://www.example.com에 localStorage 데이터가 저장됩니다. https://example.com 을 선택한다고 가정 해 보겠습니다 .
(2) 선택한 도메인의 페이지에 대해 일반적으로 localStorage를 사용합니다.
(3) 모든 https://www.example.com 페이지 ( 다른 도메인)에서 javascript를 사용하여 document.domain = "example.com";
. 그런 다음 숨겨진을 만들고 선택한 https://example.com 도메인 의 일부 페이지로 <iframe>
이동 합니다 ( 거기에 아주 작은 자바 스크립트 스 니펫을 삽입 할 수 있는 한 어떤 페이지 는 문제가되지 않습니다 . 사이트를 다시 만들려면 특별히이 목적을 위해 빈 페이지를 만드십시오. 확장 프로그램이나 Greasemonkey 스타일의 사용자 스크립트를 작성하고 있으므로 example.com의 페이지를 제어 할 수없는 경우서버에서 찾을 수있는 가장 가벼운 페이지를 선택하고 여기에 스크립트를 삽입하십시오. 어떤 종류의 "찾을 수 없음"페이지는 아마도 괜찮을 것입니다).
(4) 숨겨진 iframe 페이지의 스크립트는 (a) set document.domain = "example.com";
, (b)이 작업이 완료되면 부모 창에 알립니다. 그 후에 부모 창은 제한없이 iframe 창과 모든 개체에 액세스 할 수 있습니다! 따라서 최소 iframe 페이지는 다음과 같습니다.
<!doctype html>
<html>
<head>
<script>
document.domain = "example.com";
window.parent.iframeReady(); // function defined & called on parent window
</script>
</head>
<body></body>
</html>
userscript를 작성하는 경우는 다음과 같은 외부 액세스 기능을 추가하고 싶지 않을 수도 iframeReady()
당신에게 unsafeWindow
, 그래서 대신 사용자 정의 이벤트를 사용할 수 있습니다 메인 윈도우의 userscript을 통지 할 수있는 더 좋은 방법 :
window.parent.dispatchEvent(new CustomEvent("iframeReady"));
메인 페이지의 창에 맞춤 "iframeReady"이벤트에 대한 리스너를 추가하여 감지 할 수 있습니다.
(참고 : iframe의 도메인이 이미 example.com 인 경우에도 document.domain = "example.com"을 설정해야합니다. : document.domain 에 값을 할당하면 원본 포트 가 암시 적 으로 null로 설정되며 두 포트가 iframe에 대해 일치해야합니다. . 그리고 부모가 동일 출처 고려 여기에 참고 사항을 참조 될 : https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin )
(5)은 iframe이 준비가 있음을 부모 창을 알렸다 숨겨진되면, 부모 창에서 스크립트를 그냥 사용할 수 있습니다 iframe.contentWindow.localStorage
, iframe.contentWindow.indexedDB
, iframe.contentWindow.BroadcastChannel
, iframe.contentWindow.SharedWorker
대신 window.localStorage
, window.indexedDB
등 ...이 모든 객체에 범위가 될 선택 은 https : // example.com 출처-모든 페이지에 대해 동일한 공유 출처를 갖게됩니다!
이 기술의 가장 어색한 부분은 진행하기 전에 iframe이로드 될 때까지 기다려야한다는 것입니다. 따라서 예를 들어 DOMContentLoaded 핸들러에서 localStorage 사용을 간단하게 시작할 수는 없습니다. 또한 숨겨진 iframe이 제대로로드되지 않는지 감지하기 위해 몇 가지 오류 처리를 추가 할 수 있습니다.
분명히, 숨겨진 iframe이 페이지의 수명 동안 제거되거나 탐색되지 않는지 확인해야합니다 ... OTOH 그 결과가 무엇인지 모르겠지만 나쁜 일이 발생할 가능성이 큽니다.
그리고주의 사항 : 헤더를 사용하여 설정 / 변경 document.domain
을 차단할 수 있습니다. Feature-Policy
이 경우이 기술은 설명 된대로 사용할 수 없습니다.
그러나,에 의해 차단 될 수없는이 기술의 훨씬 더-복잡 일반화가 Feature-Policy
, 그 또한 데이터를 공유, 통신, 공유 노동자에 완전히 관련이없는 도메인을 수 있습니다 (공통 상위 도메인 오프 즉뿐 아니라 하위 도메인). @Mayank Jain은 이미 답변에서 설명했습니다.
일반적인 아이디어는 위와 마찬가지로 액세스를위한 올바른 출처를 제공하기 위해 숨겨진 iframe을 만드는 것입니다. 그러나 iframe 창의 속성을 직접 가져 오는 대신 iframe 내부의 스크립트를 사용하여 모든 작업을 수행 postMessage()
하고 및 addEventListener("message",...)
.
이것은 postMessage()
다른 출처 창 사이에서도 사용할 수 있기 때문에 작동합니다 . 하지만 메인 윈도우의 코드에서 직접 localStorage, IndexedDB 등의 API를 사용하는 것보다 iframe과 메인 윈도우 사이에서 생성하는 일종의 메시징 인프라를 통해 모든 것을 전달해야하기 때문에 훨씬 더 복잡합니다.