elb*_*tus 7 javascript cookies iframe firefox same-origin-policy
我想测试新的Firefox Storage Access API,以允许第一方存储(cookie,本地存储,indexeddb等)到其他域的iframe(但仍在我的控制之下)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Parent Domain</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.0/js.cookie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jschannel/1.0.0-git-commit1-8c4f7eb/jschannel.min.js"></script>
</head>
<body>
<div>
Cookies: <ul class="cookie-data"></ul>
</div>
<iframe
id="rpc-gateway"
src="http://child.local:8080/iframe-firefox.html"
sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin"></iframe>
<script type="text/javascript">
var chan = Channel.build({
window: document.getElementById("rpc-gateway").contentWindow,
origin: "*",
scope: "testScope"
});
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Child Domain</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.0/js.cookie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jschannel/1.0.0-git-commit1-8c4f7eb/jschannel.min.js"></script>
</head>
<body>
<button onClick="onLoginClick()">Login</button>
<script type="text/javascript">
var chan = Channel.build({
window: window.parent,
origin: "*",
scope: "testScope"
});
let onLoginClick = function(trans, params) {
document.hasStorageAccess().then(hasAccess => {
if (!hasAccess) {
console.log("no access - requesting access");
return document.requestStorageAccess();
}
}).then(_ => {
document.hasStorageAccess().then(hasAccess => {
console.log("hasAccess:", hasAccess);
window.localStorage.setItem('foo', 'bar');
})
}).catch((err) => {
console.log("hasStorageAccess() failed", err);
});
};
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
从子iframe单击“登录”按钮时,将生成以下日志输出:
no access - requesting access # iframe-firefox.html:22:25
hasAccess: true # iframe-firefox.html:27:25
Request to access cookie or storage on “http://child.local:8080/iframe-firefox.html” was blocked because we are blocking all third-party storage access requests and content blocking is enabled. # iframe-firefox.html:28:24
Run Code Online (Sandbox Code Playgroud)
可见的结论是:
我做错了什么?
更多信息:
这似乎是您所使用的 Firefox 版本中的一个错误。我在本地对您所拥有的内容进行了测试,在 Firefox 69.0.1(64 位)中,我没有收到任何错误,并且该值存储到本地存储中。当我从父 iframe 中取出沙箱标志时allow-storage-access-by-user-activation,子 iframe 无法获得本地存储的权限,因此这证实了我的设置实际上正常工作。这就是我所做的:
为父级创建了 Node.js/Express 服务器:
const express = require('express');
const cors = require('cors');
const path = require('path');
const server = express();
server.use(cors());
server.use(express.static(path.resolve('./public')));
server.listen(8080, function() {
console.log('listening on *:8080');
});
Run Code Online (Sandbox Code Playgroud)
为子级创建一个 Node.js/Express 服务器(使用不同的端口来触发同源策略):
const express = require('express');
const cors = require('cors');
const path = require('path');
const server = express();
server.use(cors());
server.use(express.static(path.resolve('./public')));
server.listen(8081, function() {
console.log('listening on *:8081');
});
Run Code Online (Sandbox Code Playgroud)
为父级创建了一个index.html(与您的几乎相同):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Parent Domain</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.0/js.cookie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jschannel/1.0.0-git-commit1-8c4f7eb/jschannel.min.js"></script>
</head>
<body>
<div>
Cookies: <ul class="cookie-data"></ul>
</div>
<iframe
id="rpc-gateway"
src="http://127.0.0.1:8081/iframe-firefox.html"
sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin"></iframe>
<script type="text/javascript">
var chan = Channel.build({
window: document.getElementById("rpc-gateway").contentWindow,
origin: "*",
scope: "testScope"
});
// Added this to try out the JSChannel
chan.call({
method: "reverse",
params: "hello world!",
success: function(v) {
console.log(v);
}
});
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
并为孩子创建了 iframe-firefox.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Child Domain</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.0/js.cookie.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jschannel/1.0.0-git-commit1-8c4f7eb/jschannel.min.js"></script>
</head>
<body>
<button onClick="onLoginClick()">Login</button>
<script type="text/javascript">
var chan = Channel.build({
window: window.parent,
origin: "*",
scope: "testScope"
});
// Other end of the JSChannel call
chan.bind("reverse", function(trans, s) {
return s.split("").reverse().join("");
});
let onLoginClick = function(trans, params) {
document.hasStorageAccess().then(hasAccess => {
if (!hasAccess) {
console.log("no access - requesting access");
return document.requestStorageAccess();
}
}).then(_ => {
document.hasStorageAccess().then(hasAccess => {
console.log("hasAccess:", hasAccess);
window.localStorage.setItem('foo', 'bar');
})
}).catch((err) => {
console.log("hasStorageAccess() failed", err);
});
};
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
一切都按预期进行...所以我非常确定问题出在您正在使用的 Firefox Developer Edition 的特定版本上。
另外,如果您想尝试一下,看看它的工作原理是否与您所拥有的不同,这里有一个指向我的设置的 zip 的链接:server.zip
如果还有什么我可以帮忙的,请告诉我。