-
Notifications
You must be signed in to change notification settings - Fork 29
Storage
luics edited this page Oct 20, 2013
·
36 revisions
跨终端跨域的存储方案
- 天猫工具栏(天猫页面左侧长条)部署在大部分天猫页面,有诸如此类的需求:
- 多个页面需要保存工具栏的显示状态
- 某些消息在指定时间间隔内显示
- 存储某些信息的删除记录
- 其他需要在多个页面间保持的数据
- 天猫页面
- 天猫多数页面具有自己的子域
- 大部分现有页面为 tmall.com 域、国际站页面属于 tmall.hk 域
- 存储方案
- Store.js:localStorage(标准浏览器 + ie 8+) + userData (ie 6/7)
- 跨域方案
- 使用 iframe 加载代理页,数据存储在代理页所在的域下 * 需要实现宿主页与代理页之间的通信
- postMessage(标准浏览器 + ie 8+) + window.name(ie 6/7)
以下对现有技术方案做分析
应考虑
- 首选 localStorage
- userData 可以做 ie 6/7 的兼容方案
不考虑
- flash 方案,不适用于移动端且
- cookie 存储上限只有 4KB,且会加重网络负担,不适合作为存储载体
参考
参考
跨域本质上还是通信问题,或说建立通信通道
参考
通信形式 | iframe | 优点 | 缺点 | 其他描述 | |
---|---|---|---|---|---|
JSONP | 单向通信 | 无域限制 | 事实标准 | ||
window.name | 单向通信 | 需要 | 2次通信,且要求 proxy 和宿主页同源(或改 domain 实现) | 请参考此篇 | |
CORS | 单向通信 | ie 6/7 不兼容 | |||
Flash URLLoader | 单向通信 | 无法跨终端 | 基于 Flash 的 CORS | ||
Server Proxy | 单向通信 | 部署复杂,扩展性受限 | |||
document.domain | 双向通信 | 需要 | 跨子域 | 需要宿主页面和 iframe 加载页改写 domain | |
FIM | 双向通信 | 需要 | 产生浏览历史纪录、数据量受限 | Fragment Identitier Messaging | |
Flash LocalConnection | 双向通信 | 无法跨终端 | |||
postMessage | 双向通信 | 需要 | ie 6/7 不兼容 | ||
Cross Frame | 双向通信 | 需要 | proxy 依赖太重 |
- 总结
跨域的方法很多,不同的应用场景我们都可以找到一个最合适的解决方案。比如单向的数据请求,我们应该优先选择JSONP或者window.name,双向通信可以采取Cross Frame,在未与数据提供方没有达成通信协议的情况下我们也可以用server proxy的方式来抓取数据。
Storage 的所有调用都只有 success 一个回调,基于这样的思路「电梯永远不会坏」,电梯即使在断电或机械故障时并不影响人们的同行;Storage 也是如此,即使代理页或其他异常导致不能支持存取数据,那么 success 回调的参数为undefined
,并不会阻塞回调更不会导致整个流程的阻塞。
尽管是要退出历史舞台的平台,为了能够让 Storage 兼容 IE6/7 着实废了一番功夫。使用 window.name 进行跨域通信首先要解决的就是并发请求的问题,我们利用队列机制,确保请求的有序进行。
由于数据存储在代理页(proxy)所在的域,数据可被所有能够加载代理页的宿主页面访问。所以保证安全关键在于服务器端控制代理页的访问来源。