localStorage的跨与实现方案

时间:2023-03-10 07:06:11
localStorage的跨与实现方案

实现原理:

HTML5 的 postMessage 为解决跨域页面通信提供了一套可控的机制, 而 localStorage 则提供了易用简洁的本地存储方案? 这两者结合起来,能否实现跨域的本地存储呢 ?

答案是可以的。假设有 a.com 和 b.com 两个页面。我们想通过 a 页面去修改 b 页面的本地数据。 我们需要做如下步奏:

  • 在 a 页面创建一个 iframe ,嵌入 b 页面
  • a 页面通过 postMessage 传递指定格式的消息给 b 页面
  • b 页面解析 a 页面传递过来的消息内容,调用localStorage API 操作本地数据
  • b 页面包装 localStorage 的操作结果,并通过 postMessage 传递给 a 页面
  • a 页面解析 b 页面传递回来的消息内容,得到 localStorage 的操作结果

localStorage的跨与实现方案

下面简单的实现一下:

在A页面:

 /*
API:
csclient.get("http://b.test.com","name",callback);
csclient.set("http://b.test.com","name","chenjian",callback);
csclient.del("http://b.test.com","name",callback);
*/
var csclient = (function () {
var _get = function (url,key,fn) {
var value = {
_key :key,
_method : "get"
};
getIframeWindow(url).postMessage(value,url);
//给window对象绑定message事件处理
addEvent(handMessage)
} var _set = function (url,key,value,fn) {
var _value = {
_key : key,
_vaule :value,
_method : "set"
};
getIframeWindow(url).postMessage(_vaule,url);
//给window对象绑定message事件处理
addEvent(handMessage)
} var _del = function () function (url,key,fn) {
var value = {
_key :key,
_method : "del"
};
getIframeWindow(url).postMessage(_vaule,url);
//给window对象绑定message事件处理
addEvent(handMessage)
} function getIframeWindow (url) {
var _iframe = document.createElement("iframe");
_iframe.src = url;
_iframe.style.display = "none";
window.body.appendChild(_iframe);
var iframeWindow = _iframe.contentWindow;
return iframeWindow;
}
function addEvent(func) {
if (window.addEventListener) {
window.addEventListener("message", func, false);
}else{
window.attachEvent("onmessage", func);
}
}
function handMessage (event) {
var event = event || window.event;
//验证是否来自预期内的域,如果不是不做处理,这样也是为了安全方面考虑
if(event.origin === url){
//处理传过来的数据;
fn(event.data);
}
}
return {
get : _get,
set : _set,
del : _del
}
})();

在B页面:

 /*
API:
cshub.init("http://a.test.com");
*/
var cshub = (function () {
var _cshub = function (url) {
addEvent(handMessage);
function handMessage(event) {
var event = event || window.event;
//验证是否来自预期内的域,如果不是不做处理,这样也是为了安全方面考虑
if(event.origin === url){
if(event.data._method=="get") {
getFn(event.data._method)
}else if (event.data._method=="set") {
setFn(event.data._method)
}else {
delFn(event.data._method)
}
}
}
function addEvent(func) {
if (window.addEventListener) {
window.addEventListener("message", func, false);
}else{
window.attachEvent("onmessage", func);
}
} function getFn (data) {
window.parent.postMessage(window.localStorage["data._key"],url);
} function setFn (data) {
window.localStorage["data._key"] = data._value;
window.parent.postMessage("设置成功");
} function delFn (data) {
window.localStorage.removeItem("data._key");
window.parent.postMessage("删除成功");
}
}
return {
init : _cshub
};
})();

上面的代码徒手写的没做测试,如果有误还望指出。谢谢