[javascript] 하위 도메인에서 localStorage 사용

쿠키를 지원할 수있는 브라우저 (IE 제외)에서 쿠키를 localStorage로 대체 하고 있습니다. 문제는 site.comwww 입니다. site.com 은 별도의 localStorage 개체를 저장합니다. 나는 www가 하위 도메인으로 간주된다고 생각합니다 (물어 보면 어리석은 결정). 사용자가 원래 site.com에 있었고 www 를 입력하기로 결정한 경우 . site.com 을 방문하면 모든 개인 데이터에 액세스 할 수 없습니다. 모든 “하위 도메인”이 기본 도메인과 동일한 localStorage를 공유하도록하려면 어떻게해야합니까?



답변

이것이 내가 여러 도메인에서 사용하는 방법입니다 …

  • 상위 도메인의 iframe 사용-parent.com
  • 그런 다음 각 child.com 도메인에서 parent.com iframe에 postMessage를 수행하십시오.
  • 여러분이해야 할 일은 parent.com iframe과 통신하기 위해 postMessage 메시지를 해석하는 방법에 대한 프로토콜을 설정하는 것뿐입니다.

나는 그것이 도움이되기를 바랍니다 🙂


답변

이 특정 문제에 대해 iframe 및 postMessage 솔루션을 사용하는 경우 하위 도메인이없는 쿠키에 데이터를 저장하는 것이 (코드 및 계산 모두) 덜 작업 할 수 있으며 아직 그렇지 않은 경우 로드시 localStorage에서 쿠키에서 가져옵니다 .

장점 :

  • 추가 iframe 및 postMessage 설정이 필요하지 않습니다.

단점 :

  • www뿐 아니라 모든 하위 도메인에서 데이터를 사용할 수 있으므로 모든 하위 도메인을 신뢰하지 않으면 작동하지 않을 수 있습니다.
  • 각 요청에 대해 데이터를 서버로 보냅니다. 좋지는 않지만 시나리오에 따라 iframe / postMessage 솔루션보다 작업량이 적을 수 있습니다.
  • 이 경우 쿠키를 직접 사용하지 않는 이유는 무엇입니까? 상황에 따라 다릅니다.
  • 도메인의 모든 쿠키에서 총 4K 최대 쿠키 크기 (댓글에서 지적 해 주신 Blake에게 감사드립니다)

나는 다른 주석가들과 동의하지만 이것은 localStorage에 대한 지정 가능한 옵션이어야하므로 해결 방법이 필요하지 않습니다.


답변

일관성과 이와 같은 문제를 피하기 위해 site.com을 www.site.com으로 리디렉션하는 것이 좋습니다.

또한 각 브라우저 기본 저장소를 사용할 수있는 PersistJS 와 같은 브라우저 간 솔루션 사용을 고려하십시오 .


답변

메인 도메인에서 쿠키로 설정-

document.cookie = "key=value;domain=.mydomain.com"

그런 다음 기본 도메인 또는 하위 도메인에서 데이터를 가져 와서 localStorage에 설정합니다.


답변

나는 xdLocalStorage를 사용하고 있는데, 이것은 LocalStorage 인터페이스를 구현하고 iframe 포스트 메시지 통신을 사용하여 도메인 간 스토리지를 지원하는 경량 js 라이브러리입니다. (angularJS 지원)

https://github.com/ofirdagan/cross-domain-local-storage


답변

이런 종류의 솔루션은 이와 같은 많은 문제를 야기합니다. 일관성 및 SEO 고려 사항을 위해 기본 도메인에서 리디렉션하는 것이 최상의 솔루션입니다.

서버 수준에서 리디렉션 수행

Nginx를 사용하여 www를 비 www로 리디렉션하는 방법

https://www.digitalocean.com/community/tutorials/how-to-redirect-www-to-non-www-with-nginx-on-centos-7

또는
경로 53과 같은 다른 수준을 사용하는 경우


답변

방법은 다음과 같습니다.

주어진 슈퍼 도메인 (예 : 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과 메인 윈도우 사이에서 생성하는 일종의 메시징 인프라를 통해 모든 것을 전달해야하기 때문에 훨씬 더 복잡합니다.