Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
21
Help us understand the problem. What is going on with this article?
@Sr_Bangs

異なるドメイン間でlocalstorageを共有する方法

More than 1 year has passed since last update.

はじめに

localStorageは基本的に同じドメイン内(厳密にはポート番号なども一致している必要がある)でしか有効ではありませんが、postMessage API(Web Messaging API)を使用することでクロスドメインでも共有することができます。

調べてみても古い記事が多かったり、サンプルのコードが無かったりだったので自分用の備忘録も兼ねてやり方をご紹介します。

構成

【ドメインA】
・localstorageのデータを持つ側。
・ドメインBからの要求に応じてlocalstorageの操作を行う。

【ドメインB】
・ドメインAに保存されているlocalstorageの値の参照や更新を要求する側。

(実際の動作確認はA側をGithub Pages、B側をローカルサーバーに置いた状態で行いました。)

ドメインA側

ドメインB側からのメッセージをトリガーにlocalstorageの操作を行っています。
(厳密にメッセージの中身を検証して処理を切り分けたりまではしていません。)

index.html
<body>
  <script>
    (function() {
      var origin = 'http://B.com';
      window.addEventListener('message', function(event) {
        // 送信元が指定のオリジンと一致していれば処理を行う
        if(event.origin === origin) {
          var message = event.data;

          // メッセージが'get'ならlocalstorageの値を返す
          if(message === 'get') {
            var storageData = localStorage.getItem('test');
            event.source.postMessage(storageData, event.origin);
          }
          // getでなければメッセージを分割してlocalstorageに保存する
          else {
            var messageArray = message.split(',');
            var key = messageArray[0];
            var value = messageArray[1];
            localStorage.setItem(key, value);
          }
        }
      });
    })();
  </script>
</body>

ドメインB側

display:noneで非表示にしたiframeでドメインA側のindex.htmlを読み込み、iframeObject.contentWindowでWindowオブジェクトを取得して、それに対してpostMessageでメッセージを送っています。

index.html
<body>
  <iframe id="iframe" src="http://A.com/index.html" style="display: none;"></iframe>
  <input type="text" name="text" id="text">
  <button id="set">ストレージに値を入れる</button>
  <button id="get">ストレージの値を取得する</button>
  <script>
  (function() {
    var iframeWindow = document.querySelector('#iframe').contentWindow;
    var $text = document.querySelector('#text');
    var $setButton = document.querySelector('#set');
    var $getButton = document.querySelector('#get');
    var origin = 'http://A.com';

    window.addEventListener('message', function(event) {
      // 送信元が指定のオリジンと一致していれば処理を行う
      if(event.origin === origin) {
        alert(event.data);
      }
    });

    $setButton.addEventListener('click', function() {
      // テキストエリアに入力されている値を送信
      iframeWindow.postMessage(`test,${$text.value}`, origin);
    });

    $getButton.addEventListener('click', function() {
      // localstorageの値の取得を要求するメッセージ送信
      iframeWindow.postMessage('get', origin);
    });

  })();
  </script>
</body>

以上になります。
もう少しややこしいロジックが必要かと思っていましたが、postMessage APIのおかげで意外と楽にできました。

21
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sr_Bangs

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
21
Help us understand the problem. What is going on with this article?