简体   繁体   English

使用javascript跨域本地存储

[英]cross domain localstorage with javascript

We have a javascript api.js which is hosted on domain api.abc.com.我们有一个 javascript api.js,它托管在域 api.abc.com 上。 It manages the local storage.它管理本地存储。

We included this javascript in our websites at abc.com and login.abc.com as a cross domain js like我们将此 javascript 包含在我们的网站 abc.com 和 login.abc.com 中作为跨域 js,例如

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

I understand that localstoarge is per domain basis.我知道 localstoarge 是基于域的。 However since api.js is loaded from api.abc.com, I expected that it will have access to local storage of api.abc.com from both the domains.但是,由于 api.js 是从 api.abc.com 加载的,我希望它可以从两个域访问 api.abc.com 的本地存储。 Unfortunately, it doesn't seem to be the case.不幸的是,情况似乎并非如此。 When api.js stores a value in localstoarge from one domain, it's not accessible to it when loaded from other domain.当 api.js 从一个域将一个值存储在 localstoarge 中时,它在从其他域加载时无法访问。

Any idea?任何的想法?

How about using cross domain postmessage and iframes?如何使用跨域 postmessage 和 iframes?

So on your wrong-domain-page you include an iframe that posts messages with the cookie data back.因此,在您的错误域页面上包含一个 iframe,该 iframe 将带有 cookie 数据的消息发布回来。

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

live example: http://codepen.io/anon/pen/EVBGyz //forked sender code with a tiiiiiny change :) :现场示例: 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);
}

Receiver code:接收器代码:

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);
}

As noticed in your post the localStorage (sessionStorage too) won't be stored on the storage related to the domain api.abc.com.正如您在帖子中所注意到的,localStorage(也是 sessionStorage)不会存储在与域 api.abc.com 相关的存储中。 If this was the case, by using CDN version of a library using localStorage you would have to share storage with all the other websites using this library.如果是这种情况,通过使用 localStorage 使用库的 CDN 版本,您将必须与使用此库的所有其他网站共享存储。

One good solution could be to use an iframe with postMessage as explained in the following stack overflow: use localStorage across subdomains一个好的解决方案可能是使用带有 postMessage 的 iframe,如以下堆栈溢出中所述: 跨子域使用 localStorage

You might try this cross-storage from Zendesk.您可以从 Zendesk 尝试这种跨存储 Basically, There are hubs and clients:基本上,有集线器和客户端:

  • hubs: reside on any server, interact directly with LocalStorage API集线器:驻留在任何服务器上,直接与 LocalStorage API 交互

  • clients: load the hub using an embedded iframe, and post messages, interact with data客户端:使用嵌入式 iframe 加载集线器,发布消息,与数据交互

Key things is you can configure the permission (get, set, delete) that each host or domain client could have.关键是您可以配置每个主机或域客户端可能拥有的权限(获取、设置、删除)。 The library is divided into two types of components: hubs and clients.该库分为两种类型的组件:集线器和客户端。

Care should be made to limit the origins of the bidirectional communication.应注意限制双向通信的来源。 As such, when initializing the hub, an array of permissions objects is passed.因此,在初始化集线器时,会传递一组权限对象。 Any messages from clients whose origin does not match the pattern are ignored, as well as those not within the allowed set of methods.来自源与模式不匹配的客户端的任何消息都将被忽略,以及那些不在允许的方法集中的消息。 The set of permissions are enforced thanks to the same-origin policy.由于同源策略,这组权限得以强制执行。 However, keep in mind that any user has full control of their local storage data - it's still client data.但是,请记住,任何用户都可以完全控制他们的本地存储数据——它仍然是客户端数据。 This only restricts access on a per-domain or web app level.这仅限制每个域或 Web 应用程序级别的访问。

The other answers all ignore the fact that you're not really operating cross-domain, just between subdomains.其他答案都忽略了这样一个事实,即您并没有真正跨域操作,而只是在子域之间操作。

You still need a hidden iframe to encapsulate the origin of the localStorage store you want to access (api.abc.com), but by setting document.domain = "abc.com" on both main window and hidden iframe, they can interact directly.你仍然需要一个隐藏的iframe来封装你要访问的localStorage store的来源(api.abc.com),但是通过在主窗口和隐藏的iframe上设置document.domain = "abc.com" ,它们可以直接交互.

Then you can literally just use hiddenIFrame.contentWindow.localStorage instead of window.localStorage , and forget about the headache of doing anything via postMessage().然后你可以直接使用hiddenIFrame.contentWindow.localStorage而不是window.localStorage ,而忘记通过 postMessage() 做任何事情的头痛。

I posted a more detailed version of this answer here: https://stackoverflow.com/a/63602446/999120我在这里发布了这个答案的更详细版本: https : //stackoverflow.com/a/63602446/999120

Use iframe to store data in local storage & postMessage API to communicate between parent domain & iframe使用 iframe 在本地存储和 postMessage API 中存储数据以在父域和 iframe 之间进行通信

  1. Create Iframe with message event listener to store data in local storage of iframe domain使用消息事件侦听器创建 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. Pass Message from parent domain to iframe to store data将消息从父域传递到 iframe 以存储数据

    document.getElementById('myFrameId').contentWindow.postMessage({ key: 'key', value: data, method: 'store' });
  3. Retrieve data from Iframe从 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