我的情况是,我有两个不同的站点,siteA.com和siteB.com,当访问者从siteA导航到siteB时,需要共享一条公共信息。我无法访问siteA的服务器端代码或导航链接,只能限制自定义和javascript。为了共享信息,我在siteC.com上构建了一个完全由我控制的新页面,然后将此页面作为iframe添加到siteA和siteB。我使用postMessage
方法从iframe中获取和设置cookie,每个网站都运行正常,但实际上我最终得到了两个不同的cookie,每个siteA和siteB一个,即使cookie属于siteC因为它是由iframe中的页面设置的,通过F12调试器确认。我本来希望有一个cookie,两个网站都可以通过iframe共享相同的cookie,我在这里遗漏了一些东西,这是否可行,还是有另外一种方法可以做到这一点?
这是我在siteC的页面加载到iframe
的代码<!DOCTYPE html>
<html>
<head>
<title>iframe source</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function () {
var ck = document.cookie;
var expDate = new Date();
expDate.setFullYear(expDate.getFullYear() + 20)
$("#auditlog").append("iframe loaded<br/>");
if (ck) {
$("#auditlog").append("cookie exists<br/>");
} else {
$("#auditlog").append("cookie not set<br/>");
}
// Assign handler to message event
if (window.addEventListener) {
window.addEventListener('message', messageHandler, false);
} else if (window.attachEvent) { // ie8
window.attachEvent('onmessage', messageHandler);
}
})
function messageHandler(e) {
var msg = {};
var response;
// Check origin
if (e.origin === 'http://siteA' || e.origin === 'http://siteB') {
// Retrieve data sent in postMessage
msg = JSON.parse(e.data);
if (msg.action == "getCookie") {
response = getCookie();
} else if (msg.action == "setCookie") {
setCookie(msg.payload);
response = "cookie set";
} else {
response = "action not supported";
}
// Send reply to source of message
e.source.postMessage(response, e.origin);
}
}
function setCookie(cookieVal) {
var expDate = new Date();
expDate.setFullYear(expDate.getFullYear() + 20)
document.cookie = cookieVal + "; expires=" + expDate.toUTCString();
}
function getCookie() {
return document.cookie;
}
</script>
</head>
<body>
<div id="auditlog"></div>
<div id="cookieinfo"></div>
</body>
</html>
这是我在siteA和siteB的页面的代码,两者都使用相同的代码,这是我为了测试集合并在iframe中获取cookie函数而设置的示例
<!DOCTYPE html>
<html>
<head>
<title>Main content page</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function () {
// Assign handler to message event
if (window.addEventListener) {
window.addEventListener('message', messageHandler, false);
} else if (window.attachEvent) { // ie8
window.attachEvent('onmessage', messageHandler);
}
$("#btnGetIframeCookie").click(function () {
var postMsg = {
action:"getCookie"
}
// get reference to window inside the iframe
var wn = document.getElementById('cookieiframe').contentWindow;
// postMessage arguments: data to send, target origin
wn.postMessage(JSON.stringify(postMsg), 'http://siteC');
})
$("#btnSetIframeCookie").click(function () {
var cookieVal = $("#txtCookieValue").val();
var postMsg = {
action: "setCookie",
payload: cookieVal
}
var wn = document.getElementById('cookieiframe').contentWindow;
// postMessage arguments: data to send, target origin
wn.postMessage(JSON.stringify(postMsg), 'http://siteC');
})
})
function messageHandler(e) {
if (e.origin === 'http://siteC') {
$("#divMessages").append("response from iframe: <br/>" + e.data + "<br/>");
}
}
</script>
</head>
<body>
<div>
This is the iframe container
</div>
<div>
<input type="button" id="btnGetIframeCookie" value="Get iframe cookie" />
</div>
<div>
<input type="text" size="60" id="txtCookieValue" />
<input type="button" id="btnSetIframeCookie" value="Set iframe cookie" />
</div>
<iframe id="cookieiframe" src="http://siteC/iframe/index.html" style="width: 300px; height: 300px; border:1px solid black;"></iframe>
<div id="divMessages"></div>
</body>
</html>
使用此设置,如果我通过iframe通过值"keyabc=value123"
设置来自siteA的cookie,我可以读回相同的cookie,但是当我转到具有相同页面的siteB时那里的iframe,我没有cookie,直到我在那里设置一个cookie,例如"keyabc=value456"
。现在,如果我在C:\Users\aakoehle\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\#!001\MicrosoftEdge\Cookies
查看我的实际cookie文件,我会看到两个文件,一个是我设置的每个值,都有siteC的路径。我还为每个浏览器选项卡启动了F12工具,每个选项卡都显示了它自己的属于siteC的cookie。
- 更新 -
在我这里发布的代码的当前版本中,我现在只在Edge浏览器中看到cookie问题。 Chrome和IE正在按预期在siteA和siteB之间共享一个cookie。
答案 0 :(得分:1)
以下是使用localStorage
和postMessage
在跨源网站之间共享数据的示例。
site1:localhost:9091
<html>
<body>
<h1>site 1</h1>
<button id='postBtn'>Post message</button>
<br/>
<iframe id='commonSite' src='http://localhost:9093/commonSite.html' style='height:150px'></iframe>
<script>
(function () {
var commonSite = document.querySelector('#commonSite').contentWindow;
var postCounter = localStorage.getItem('postCounter');
postCounter = postCounter != null ? +postCounter : 1;
var commonOrigin = 'http://localhost:9093';
document.querySelector('#postBtn').onclick = function () {
commonSite.postMessage(postCounter++, commonOrigin);
localStorage.setItem('postCounter', postCounter);
console.log('site 1 posted');
}
})();
</script>
</body>
</html>
site2:localhost:9092
<html>
<body>
<h1>site 2</h1>
<button id='postBtn'>Post message</button>
<br/>
<iframe id='commonSite' src='http://localhost:9093/commonSite.html' style='height:150px'></iframe>
<script>
(function () {
var commonSite = document.querySelector('#commonSite').contentWindow;
var postCounter = localStorage.getItem('postCounter');
postCounter = postCounter != null ? +postCounter : 1;
var commonOrigin = 'http://localhost:9093';
document.querySelector('#postBtn').onclick = function () {
commonSite.postMessage(postCounter++, commonOrigin);
localStorage.setItem('postCounter', postCounter);
console.log('site 2 posted');
}
})();
</script>
</body>
</html>
commonSite:localhost:9093
<html>
<body>
<h3>Common site</h1>
<h4> Site 1 count: <span id='count1'></span></h3>
<h4> Site 2 count: <span id='count2'></span></h3>
<script>
(function () {
console.log('Adding message listener');
var origin1 = 'http://localhost:9091';
var origin2 = 'http://localhost:9092';
var count1 = document.querySelector('#count1');
var count2 = document.querySelector('#count2');
if(localStorage.getItem('count1')) {
count1.textContent = localStorage.getItem('count1');
}
if(localStorage.getItem('count2')) {
count2.textContent = localStorage.getItem('count2');
}
window.addEventListener('message', function (event) {
var origin = event.origin;
var data = event.data;
if(origin === origin1) {
localStorage.setItem('count1', data);
count1.textContent = localStorage.getItem('count1');
} else if(origin === origin2) {
localStorage.setItem('count2', data);
count2.textContent = localStorage.getItem('count2');
}
console.log('received (' + data + ') from ' + origin);
}, false);
})();
</script>
</body>
</html>