繁体   English   中英

使用javascript跨域本地存储

[英]cross domain localstorage with javascript

我们有一个 javascript api.js,它托管在域 api.abc.com 上。 它管理本地存储。

我们将此 javascript 包含在我们的网站 abc.com 和 login.abc.com 中作为跨域 js,例如

<script src="http://api.abc.com/api.js">

我知道 localstoarge 是基于域的。 但是,由于 api.js 是从 api.abc.com 加载的,我希望它可以从两个域访问 api.abc.com 的本地存储。 不幸的是,情况似乎并非如此。 当 api.js 从一个域将一个值存储在 localstoarge 中时,它在从其他域加载时无法访问。

任何的想法?

如何使用跨域 postmessage 和 iframes?

因此,在您的错误域页面上包含一个 iframe,该 iframe 将带有 cookie 数据的消息发布回来。

这是跨域 postmessages 的一个可靠示例: http ://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage

现场示例: http ://codepen.io/anon/pen/EVBGyz //分叉的发件人代码,有一个 tiiiiiny 变化:):

window.onload = function() {
    // Get the window displayed in the iframe.
    var receiver = document.getElementById('receiver').contentWindow;

    // Get a reference to the 'Send Message' button.
    var btn = document.getElementById('send');

    // A function to handle sending messages.
    function sendMessage(e) {
        // Prevent any default browser behaviour.
        e.preventDefault();

        // Send a message with the text 'Hello Treehouse!' to the new window.
        receiver.postMessage('cookie data!', 'http://wrong-domain.com');
    }

    // Add an event listener that will execute the sendMessage() function
    // when the send button is clicked.
    btn.addEventListener('click', sendMessage);
}

接收器代码:

window.onload=function(){
    var messageEle=document.getElementById('message');
    function receiveMessage(e){
        if(e.origin!=="http://correct-domain.com")
        return;
        messageEle.innerHTML="Message Received: "+e.data;
    }
    window.addEventListener('message',receiveMessage);
}

正如您在帖子中所注意到的,localStorage(也是 sessionStorage)不会存储在与域 api.abc.com 相关的存储中。 如果是这种情况,通过使用 localStorage 使用库的 CDN 版本,您将必须与使用此库的所有其他网站共享存储。

一个好的解决方案可能是使用带有 postMessage 的 iframe,如以下堆栈溢出中所述: 跨子域使用 localStorage

您可以从 Zendesk 尝试这种跨存储 基本上,有集线器和客户端:

  • 集线器:驻留在任何服务器上,直接与 LocalStorage API 交互

  • 客户端:使用嵌入式 iframe 加载集线器,发布消息,与数据交互

关键是您可以配置每个主机或域客户端可能拥有的权限(获取、设置、删除)。 该库分为两种类型的组件:集线器和客户端。

应注意限制双向通信的来源。 因此,在初始化集线器时,会传递一组权限对象。 来自源与模式不匹配的客户端的任何消息都将被忽略,以及那些不在允许的方法集中的消息。 由于同源策略,这组权限得以强制执行。 但是,请记住,任何用户都可以完全控制他们的本地存储数据——它仍然是客户端数据。 这仅限制每个域或 Web 应用程序级别的访问。

其他答案都忽略了这样一个事实,即您并没有真正跨域操作,而只是在子域之间操作。

你仍然需要一个隐藏的iframe来封装你要访问的localStorage store的来源(api.abc.com),但是通过在主窗口和隐藏的iframe上设置document.domain = "abc.com" ,它们可以直接交互.

然后你可以直接使用hiddenIFrame.contentWindow.localStorage而不是window.localStorage ,而忘记通过 postMessage() 做任何事情的头痛。

我在这里发布了这个答案的更详细版本: https : //stackoverflow.com/a/63602446/999120

使用 iframe 在本地存储和 postMessage API 中存储数据以在父域和 iframe 之间进行通信

  1. 使用消息事件侦听器创建 iframe 以将数据存储在 iframe 域的本地存储中

    window.addEventListener("message", handleMessage, false); function handleMessage(e) { let {key, value, method} = e.data; if (method == 'store') { window.localStorage.setItem(key, value); // Store data in iframe domain local storage } else if (method == 'retrieve') { let response = window.localStorage.getItem(key); e.source.postMessage({ key, response, method: 'response' }, '*'); // Retrieve local storage data }

    }

  2. 将消息从父域传递到 iframe 以存储数据

    document.getElementById('myFrameId').contentWindow.postMessage({ key: 'key', value: data, method: 'store' });
  3. 从 Iframe 检索数据

     document.getElementById('myFrameId').contentWindow.postMessage({ method: 'response', key: 'key' }); window.addEventListener("message", handleResponse, false); function handleResponse(e) { let {key,value,method} = e.data if (method == 'response') { console.log('Response Key', key); console.log('Response value', value) } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM