使用 Iframe 跨域访问子页面无法获取 子页面的localstorage?-灵析社区

一颗西兰花

关于使用 Iframe 进行跨域访问 localstorage 的问题。 A 页面:[http://127.0.0.1:5173/localstorage.](https://link.segmentfault.com/?enc=Xedj5SYCxwPXmRLJhvpRMQ%3D%3D.ksecDFfB9R04orX0nvf9cVlBt0VdLsm5egoE5Ut10GNicQ9IbSX53BKgAqZNnfud) 新窗口打开进行 localstorage.setItem("token", "test") B页面:[http://localhost:7456/localstorage.html](https://link.segmentfault.com/?enc=b%2Bk%2FBgbaRSmB0SqukWHbvA%3D%3D.UH5GsRvlrFr3mFdULKjP4Uin%2B%2BmyGgA9SNEwcXCWtvJUt1XwsPxX3yDmpaRQarGo) 中想要访问 A 页面的 localstorage. 方法尝试使用 iframe和 postMessage进行传递。 在 B 页面使用 iframe 打开 A 页面,进行消息传递这些都没有问题。 关键问题:单独使用新窗口打开 A 页面localstorage.getItem("token")是有值的,但是使用 iframe 中打开 A 页面,就无法获取他的 localstorage。查看源是没有问题的啊 浏览器环境:Chrome,不是无痕模式。 希望有大佬帮忙解决一下这个问题。 如果把 A 页面的地址换成 [http://localhost:5173/localstorage](https://link.segmentfault.com/?enc=po9DlxX6ZVjKwgEDuxDW%2FQ%3D%3D.ww908zVHYKfRxr0QicoS6VUU4K9GawDJWw3OkbP76mTGdpGLaG3HsDkty5IYEae0) 或者把 B 页面的地址换成[http://127.0.0.1:7456/localstorage.html](https://link.segmentfault.com/?enc=hSx86lKuKhxTYghVY4%2Bsvg%3D%3D.gLaHLjHgdOKr%2BZlHIcGzchAZ6eXzsSNHzkj%2BYiwVMCNFgAjQbt%2BUySREjWsbTP%2F%2B) 一切正常,但是这不就是同源了吗 添加截图和代码 这是单独窗口打开 A 页面,使用 127.0.0.1 打开。可以获取 localstorage ![这是单独窗口打开 A 页面,使用 127.0.0.1 打开。可以获取 localstorage](https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241014/737dd01f35dcca924c18daf496bd7fbb.png) 这是 B 页面,使用 localhost:80802 打开。使用 iframe 打开 却不能访问 A 的 localstorage ![这是 B 页面,使用 localhost:80802 打开。使用 iframe 打开 http://127.0.01:80801/a.html 却不能访问 A 的 localstorage](https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241014/2565dd68bba33508df1c36d4f12e59dd.png) 如果将 B 使用 [http://127.0.0.1:8082/b.html](https://link.segmentfault.com/?enc=cXmUMaPkOlBV8ybT0BjF6g%3D%3D.qHyKw8ZmKAJONjs7AWrh9ljGEOHWJaY04XvSsbM4vZw%3D) 打开,就可以获取的到 ![](https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241014/2a433c9a913069337be6a88b84986a8e.png) 代码部分: a.html A Page window.addEventListener('message', function (event) { if (event.origin === "http://127.0.0.1:8081") return; const localStorage = window.localStorage.getItem("test") console.log("localStorage data is: " + localStorage) // 监听父窗口发送过来的数据向服务器发送post请求 const data = event.data console.log(event) const localData = window.localStorage.getItem('test') console.log(localData) window.parent.postMessage(localData, "*"); }, false) B.html B Page const iframe = document.createElement('iframe') iframe.src = 'http://127.0.0.1:8081/a.html' document.body.appendChild(iframe) window.addEventListener("message", function (event) { if (event.origin !== "http://127.0.0.1:8081") return; const data = event.data; console.log(event); }, false); // window.onload = function () { // window.frames[0].postMessage("hello", 'http://127.0.0.1:8081') // } setTimeout(() => { iframe.contentWindow.postMessage("hello", 'http://127.0.0.1:8081') }, 3000)

阅读量:190

点赞量:0

问AI
可以获取到啊,看看你是不是有一些其他的业务代码影响到了? 还是说你的 "Storage" 里面本来就是空的,所以你获取不到? "图片.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241014/ec02e20cd1da25d03205019a53425c7d.png) *** Edit 01/15/24 补充使用 "localhost:8080" 访问 "127.0.0.1:8081" 截图: "图片.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241014/b7a83d033897d0ec541bf238bb0ec844.png) Edit 01/16/24 所以OP其实想要做单点登录,那么简单的如果是同一个顶级域名下的不同的子域名。可以通过在设置 "Cookie" 时把 "domain" 设置为顶级域名。这样就会应用到顶级域名下的所有子域名。 如果不是同一个顶级域名下的,那么就是通过CAS的方式来实现单点登录,简易流程如下: 1. 用户打开应用页面; 2. 应用发现用户未登录; 3. 跳转到 "CAS server" 登录页让用户登录; 4. 登录成功,服务端生成 "Service Ticket",并将 Ticket 作为参数携带跳转回应用; 5. 应用获取 Ticket 参数并发送给后端验证; 6. 后端验证 Ticket 是否有效,验证通过后完成登录操作。 "单点登录(SSO)看这一篇就够了" (https://segmentfault.com/a/1190000040049585)