使用 iframe 在不同域之间共享 localStorage 数据不起作用

问题描述 投票:0回答:2

我正在尝试阅读这篇文章,该文章教我们如何在嵌入了 iframe 的情况下在域之间共享本地存储数据。

https://www.internetkatta.com/share-cookies-or-local-storage-data- Between-cross-domain

为了尝试一下,我创建了两个单独的项目,分别拥有自己的 html 文件和索引文件。然后,我使用 VS Code 的实时服务器在服务器中启动了这两个 html 文件。我试图让

http://127.0.0.1:5500/getlocalstorage.html
将用户登录数据传递给
http://127.0.0.1:5501/getlocalstorage.html
,但是,它在本地存储选项卡中没有返回任何数据,仅显示为:

我在这里做错了什么吗?我试图将虚拟登录信息从 localhost:5500 传递到 localhost:5501。请参阅下面我的代码:

本地主机5500的index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <script>
      function postCrossDomainMessage(msg) {
        var win = document.getElementById("ifr").contentWindow;
        win.postMessage(msg, "http://127.0.0.1:5500/");
      }
      var postMsg = { login: "user" }; // this is just example
      postCrossDomainMessage(postMsg);
    </script>
    <script src="index.js"></script>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <iframe
      style="display: none"
      src="http://127.0.0.1:5501/getlocalstorage.html"
      id="ifr"
    ></iframe>
    <h1>http://127.0.0.1:5500/index.html</h1>
  </body>
</html>

本地主机5501的html文件(getlocalstorage.html):

<!DOCTYPE html>
<html lang="en">
  <head>
    <script>
      var PERMITTED_DOMAIN = "http://127.0.0.1:5500";
      /**
       * Receiving message from other domain
       */
      window.addEventListener("message", function (event) {
        if (event.origin === PERMITTED_DOMAIN) {
          //var msg = JSON.parse(event.data);
          // var msgKey = Object.keys(msg)[0];
          if (event.data) {
            localStorage.setItem("localstorage", event.data);
          } else {
            localStorage.removeItem("localstorage");
          }
        }
      });
    </script>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>http://127.0.0.1:5501/getlocalstorage.html</h1>
  </body>
</html>

控制台中显示新错误

localhost 5500 控制台错误

你看到我在这里可能做错了什么吗?谢谢!

这是在 localhost 5500 选项卡中:

在 localhost 5501 localstorage 选项卡中:

javascript local-storage same-origin-policy session-storage postmessage
2个回答
1
投票

script
标签位于
iframe
标签之前。它也在创建
iframe
之前执行。因此,搜索
ifr
返回
null
并且
null
没有
contentWindow
,这会引发错误。您需要在页面加载后推迟 JS 执行,如下所示:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script>
      function postCrossDomainMessage(msg) {
        var win = document.getElementById("ifr").contentWindow;
        win.postMessage(msg, "http://127.0.0.1:5500/");
      }
      function load() {
          var postMsg = { login: "user" }; // this is just example
          postCrossDomainMessage(postMsg);
      }
    </script>
    <script src="index.js"></script>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body onload="load()">
    <iframe
      style="display: none"
      src="http://127.0.0.1:5501/getlocalstorage.html"
      id="ifr"
    ></iframe>
    <h1>http://127.0.0.1:5500/index.html</h1>
  </body>
</html>

注意,

load
函数不会在
script
标签中执行,只是定义。触发它的是
onload
中定义的
body
事件。

编辑

localStorage.setItem("localstorage", event.data);
行使用
localStorage
键和
'localStorage'
值将项目存储到
[Object object]
中,因为在localStorage中您将存储字符串。因此,您需要对您拥有的对象进行字符串化。所以,你需要做类似的事情

localStorage.setItem("localstorage", JSON.stringify(event.data));

您可以通过

阅读它

JSON.parse(localStorage.getItem("localStorage"))

示例


0
投票

这还有效吗? 因为我尝试执行相同的 iFrame 嵌入和 postmessage 来在 2 个域之间共享本地存储值。但现在不行了

© www.soinside.com 2019 - 2024. All rights reserved.