cross-storage 浏览器 Web 跨域本地缓存
cross-storage 浏览器 Web 跨域本地缓存。允许跨不同域的多个浏览器窗口/选项卡共享单个本地存储。使用 ES6 Promise 提供一个 API。
该库是共享根域 cookie 的一种方便的替代方法。与cookie不同的是,客户端的数据不限于几千字节--最高可达249万个字符。对于客户端很重的应用程序,您可以通过避免cookie来减少几KB的请求头。这都要感谢 LocalStorage,它可以在 IE8+、FF 3.5+、Chrome 4+以及大多数移动浏览器中使用。
它怎么工作?库分为两种类型的组件:Hub 和 Client。Hub 驻留在选择的主机上,并直接与LocalStorageAPI交互。然后,客户端通过嵌入的 iframe 和 POST 消息加载所述 Hub,请求存储、检索和删除数据。这允许多个 Client 访问和共享位于单个存储区中的数据。
应注意限制双向交流的起源。因此,在初始化 Hub 时,传递一个权限对象数组。来自起源与模式不匹配的客户端的任何消息都将被忽略,以及那些不在允许的方法集合中的消息。由于相同的来源策略,权限集被强制执行。但是,请记住,任何用户都可以完全控制本地存储数据,仍然是客户端数据。这只会限制每个域或web应用程序级别上的访问。
Hub
// Config s.t. subdomains can get, but only the root domain can set and del
CrossStorageHub.init([
{origin: /\.example.com$/, allow: ['get']},
{origin: /:\/\/(www\.)?example.com$/, allow: ['get', 'set', 'del']}
]);
注意用于匹配字符串末尾的 $。上面示例中的 RegExps 将匹配像 valid.example.com这样的起源,但不匹配 void.example.com.malicious.com。
Client
var storage = new CrossStorageClient('https://store.example.com/hub.html');
storage.onConnect().then(function() {
return storage.set('newKey', 'foobar');
}).then(function() {
return storage.get('existingKey', 'newKey');
}).then(function(res) {
console.log(res.length); // 2
}).catch(function(err) {
// Handle error
});
安装
可以通过 bower 安装:
bower install cross-storage
或者是使用 npm 安装:
npm install cross-storage
也可以使用 browserify:
var CrossStorageClient = require('cross-storage').CrossStorageClient;
var CrossStorageHub = require('cross-storage').CrossStorageHub;
在为 Hub 服务时,您可能希望根据 客户机/Hub 位置设置服务器的 CORS 和 CSP 头。例如:
{
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE',
'Access-Control-Allow-Headers': 'X-Requested-With',
'Content-Security-Policy': "default-src 'unsafe-inline' *",
'X-Content-Security-Policy': "default-src 'unsafe-inline' *",
'X-WebKit-CSP': "default-src 'unsafe-inline' *",
}
如果使用内联 JS 创建 Hub,则需要指定 unsafe-inline
对于 CSP 头。否则,如果简单地通过另一个资源包含 init 代码,则可以忽略它。
API
CrossStorageHub.init(permissions)
接受一个具有两个键的对象数组:origin 和 allow。源的值应该是一个 RegExp,并允许一个字符串数组。然后初始化跨存储中心以接受来自任何匹配源的请求,从而允许访问相关的方法列表。方法可以包括任意一个:get、set、del、getKeys 和 CLEAR。一旦完成,将向父窗口发送“ready”消息。
CrossStorageHub.init([
{origin: /localhost:3000$/, allow: ['get', 'set', 'del', 'getKeys', 'clear']}
]);
new CrossStorageClient(url, [opts])
构造一个新的跨存储客户端,将 url 提供给 Hub。默认情况下,在指向 url 的文档正文中创建一个 iframe。它还接受 Options 对象,该对象可能包括超时值、框架ID 和 Promise。超时(以毫秒为单位)应用于每个请求,默认为 5000ms。Options 对象还可能包含一个 FraId,标识要在其上安装侦听器的现有框架。如果承诺键被提供给承诺的构造函数,则将使用该允诺库而不是默认的 window.promisel。
var storage = new CrossStorageClient('http://localhost:3000/hub.html');
var storage = new CrossStorageClient('http://localhost:3000/hub.html', {
timeout: 5000,
frameId: 'storageFrame'
});
CrossStorageClient.prototype.onConnect()
返回在与跨存储中心建立连接时履行的 Promise。它的使用是必要的,以避免在初始化完成之前发送任何请求。
storage.onConnect().then(function() {
// ready!
});
CrossStorageClient.prototype.set(key, value)
设置指定值的键。返回在成功时实现的 Promise,或者如果发生设置键的任何错误或请求超时,则返回被拒绝的 Promise。
storage.onConnect().then(function() {
return storage.set('key', JSON.stringify({foo: 'bar'}));
});
CrossStorageClient.prototype.get(key1, [key2], [...])
接受检索其值的一个或多个键。返回关于 Hub 响应或超时的 Promise 对象。在成功时,如果只传递一个参数,则使用键的值来实现。否则,它将使用一个值数组进行解析。在失败时,它将与相应的错误消息一起被拒绝。
storage.onConnect().then(function() {
return storage.get('key1');
}).then(function(res) {
return storage.get('key1', 'key2', 'key3');
}).then(function(res) {
// ...
});
CrossStorageClient.prototype.del(key1, [key2], [...])
接受一个或多个键进行删除。返回关于集线器响应或超时的 Promise 对象。
storage.onConnect().then(function() {
return storage.del('key1', 'key2');
});
CrossStorageClient.prototype.getKeys()
返回一个 Promise 对象,该 Promise 对象 在解析后传递当前存储中的一个键数组。
storage.onConnect().then(function() {
return storage.getKeys();
}).then(function(keys) {
// ['key1', 'key2', ...]
});
CrossStorageClient.prototype.clear()
返回一个 Promise,该 Promise 在解析后指示所有 localStorage 数据已被清除。
storage.onConnect().then(function() {
return storage.clear();
});
CrossStorageClient.prototype.close()
删除iframe并将连接状态设置为false。客户端在被调用后不能再使用。
storage.onConnect().then(function() {
return storage.set('key1', 'key2');
}).catch(function(err) {
// Handle error
}).then(function() {
storage.close();
});
兼容性
为了与较旧的浏览器兼容,只需加载一个 Promise polyfill 例如 es6-promise。
您也可以使用RSVP或任何其他符合ES6的承诺库。支持IE8及以上使用上述填充。兼容视图中的IE8也需要一个JSON填充。还请注意catch
是IE8中的一个保留字,因此使用承诺来处理错误可以这样做:
storage.onConnect().then(function() {
return storage.get('key1');
}).then(function(res) {
// ... on success
})['catch'](function(err) {
// ... on error
});
关于 Safari 7+ (OSX, iOS)
默认情况下,Safari 7+ 所有跨域本地存储访问都将禁用。这是 阻止cookie和其他网站数据 隐私设置被设置为 来自第三方和广告商 的结果。任何跨存储客户端代码都不会崩溃,但是,它只能访问沙箱,孤立的本地存储实例。因此,以前由其他来源设定的数据都无法获取。如果是一个选项,您可以回到为这些用户代理使用根 cookie,或者从服务器端存储请求数据。
压缩
大多数与本地存储兼容的浏览器提供至少5MB的存储。但是键和值被定义为DOMStrings,它是使用单个16位序列编码的UTF-8.这意味着250万个ASCII字符的字符串将使用5MB,因为它们是每个字符2个字节。
如果需要最大化存储空间,请考虑使用 lz-string。对于较小的字符串,压缩时会看到大小减少50%,这将给您带来更接近500万字符的效果。此时,您只受到字符串的平均压缩速率的限制。
相关链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论