一,背景

因为网站系统的日益庞大,不同域名业务,甚至不同合作方网站的cookie可能或多或少需要进行共享使用,遇到这个情况的时候,大家一般想到的是使用登录中心分发cookie状态再进行同步进行解决,成本较高而且实施起来比较复杂和麻烦。
因为cookie在跨域的情况下,浏览器根本不允许互相访问的限制,为了突破这个限制,所以有了以下这个实现方案,使用postmessage和localstorage进行数据跨域共享。
原理比较简单,但是遇到的坑也不少,这里梳理一下,做个备份。
二,API设计
背景中说过我们使用localstorage来代替cookie,本身localstorage和cookie就有一些使用上的区别,比如localstorage的容量更大,但是不存在过期时间,虽然容量大,但在不同的浏览器上也都有空间上限,操作不好很容易崩溃,还有就是postmessage虽然支持跨域,安全问题和api的异步化也给使用带来了一些麻烦,我们如何把这个模块设计的更易用呢?
先看下我设计的API:
| import { crosData } from 'base-tools-crossDomainData'; var store = new crosData({ iframeUrl:"somefile.html", //共享iframe地址,iframe有特殊要求,详见模板文件 expire:'d,h,s' //单位天,小时,秒 默认过期时间,也可以种的时候覆盖 }); store.set('key','val',{ expire:'d,h,s' //option 可带过期时间,覆盖expire }).then((data)=>{ //异步方法,如果种失败,会进入catch事件 //data {val:'val',key:'key',domain:'domain'}; }).catch((err)=>{ console.log(err); }); store.get('key',{ domain:'(.*).sina.cn' //可以指定域名,也可以使用(.*)来匹配正则字符串,返回的val信息会带着domain信息,不填写则返回本域的 }).then((vals)=>{ console.log(val) //异步获取存储数据,可能多个,是个数组 [{},{}] }).catch((err)=>{ }); store.clear('key').then().catch(); //只清楚当前域下的key,不允许清除其他域下的key,只能读 |
一个模块上手快不快主要看api,所以对于一个数据共享模块,我认为支持set,get,clear这3个方法就ok了,因为postmessage本身是个一来一回的异步的行为,包装成promise的肯定更为合适和易用。因为localstorage不支持过期时间,所以需要一个全局的过期时间配置,当然也可以在set的时候进行单独配置,而get的时候我们可以指定获取某个域下的数据或者多个域下的数据,因为key名可能重复,但是域只有一个。这里就牵扯到了数据的管理,后边单独来说,最后clear和set的api只能种本域的数据,不可以操作其他域下的数据,get被允许。
下面我们看一下,client端的设置和API:
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>crosData</title> </head> <body> <script> window.CROS = { domain:/(.*).sina.cn/, //或者你允许的域名,支持正则和*通配符 lz:false //是否开启lz压缩val字符 }; </script> <script src="http://cdn/sdk.js"></script> </body> </html> |









