Mau*_*oer 48 javascript cookies
我有一个应用程序需要检查客户端浏览器是否启用了第三方cookie.有谁知道如何在JavaScript中执行此操作?
Ala*_* H. 70
第三方通过HTTP设置和读取cookie(不是在JavaScript中).
因此,我们需要两个外部域请求来测试是否启用了第三方cookie:
由于DOM安全模型,我们无法使用XMLHTTPRequest(Ajax).
显然,您无法并行加载这两个脚本,或者第二个请求可能在第一个请求的响应返回之前进行,并且测试cookie将不会被设置.
鉴于:
该.html
文件位于一个域上,并且
这些.js.php
文件位于第二个域,我们有:
保存为 third-party-cookies.html
<!DOCTYPE html>
<html>
<head id="head">
<meta charset=utf-8 />
<title>Test if Third-Party Cookies are Enabled</title>
<style type="text/css">
body {
color: black;
background: white none;
}
.error {
color: #c00;
}
.loading {
color: #888;
}
.hidden {
display: none;
}
</style>
<script type="text/javascript">
window._3rd_party_test_step1_loaded = function(){
// At this point, a third-party domain has now attempted to set a cookie (if all went to plan!)
var step2Url = 'http://third-party.example.com/step2.js.php',
resultsEl = document.getElementById('3rd_party_cookie_test_results'),
step2El = document.createElement('script');
// Update loading / results message
resultsEl.innerHTML = 'Stage one complete, loading stage 2…';
// And load the second part of the test (reading the cookie)
step2El.setAttribute('src', step2Url);
resultsEl.appendChild(step2El);
}
window._3rd_party_test_step2_loaded = function(cookieSuccess){
var resultsEl = document.getElementById('3rd_party_cookie_test_results'),
errorEl = document.getElementById('3rd_party_cookie_test_error');
// Show message
resultsEl.innerHTML = (cookieSuccess ? 'Third party cookies are <b>functioning</b> in your browser.' : 'Third party cookies appear to be <b>disabled</b>.');
// Done, so remove loading class
resultsEl.className = resultsEl.className.replace(/\bloading\b/,' ');
// And remove error message
errorEl.className = 'hidden';
}
</script>
</head>
<body id="thebody">
<h1>Test if Third-Party Cookies are Enabled</h1>
<p id="3rd_party_cookie_test_results" class='loading'>Testing…</p>
<p id="3rd_party_cookie_test_error" class="error hidden">(If this message persists, the test could not be completed; we could not reach the third-party to test, or another error occurred.)</p>
<script type="text/javascript">
window.setTimeout(function(){
var errorEl = document.getElementById('3rd_party_cookie_test_error');
if(errorEl.className.match(/\berror\b/)) {
// Show error message
errorEl.className = errorEl.className.replace(/\bhidden\b/,' ');
} else {
}
}, 7*1000); // 7 sec timeout
</script>
<script type="text/javascript" src="http://third-party.example.com/step1.js.php"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
保存为 step1.js.php
这是用PHP编写的,因此我们可以在文件加载时设置cookie.(当然,它可以用任何语言编写,甚至可以在服务器配置文件中完成.)
<?php
header('Content-Type: application/javascript; charset=UTF-8');
// Set test cookie
setcookie('third_party_c_t', 'hey there!', time() + 3600*24*2);
?>
window._3rd_party_test_step1_loaded();
Run Code Online (Sandbox Code Playgroud)
保存为 step2.js.php
这是用PHP编写的,所以我们可以在响应之前读取服务器端的cookie.我们还清除了cookie,因此可以重复测试(如果你想搞乱浏览器设置并重新尝试).
<?php
header('Content-Type: application/javascript; charset=UTF-8');
// Read test cookie, if there
$cookie_received = (isset($_COOKIE['third_party_c_t']) && $_COOKIE['third_party_c_t'] == 'hey there!');
// And clear it so the user can test it again
setcookie('third_party_c_t', '', time() - 3600*24);
?>
window._3rd_party_test_step2_loaded(<?php echo ($cookie_received ? 'true' : 'false'); ?>);
Run Code Online (Sandbox Code Playgroud)
最后一行使用三元运算符输出文字Javascript true
或false
取决于测试cookie是否存在.
可通过https://alanhogan.github.io/web-experiments/3rd/third-party-cookies.html获取您的测试乐趣.
(作为最后一点 - 不要在没有他们许可的情况下使用别人的服务器测试第三方cookie.它可能会自发破坏或注入恶意软件.这很粗鲁.)
Goj*_*zic 42
这是一个纯JS解决方案,不需要任何服务器端代码,所以它可以在静态CDN上运行:https://github.com/mindmup/3rdpartycookiecheck - 第一个脚本在代码中设置cookie,然后重定向到第二个脚本这会将消息发布到父窗口.
您可以使用https://jsfiddle.net/tugawg8y/试用实时版本
客户端HTML:
third party cookies are <span id="result"/>
<iframe src="https://mindmup.github.io/3rdpartycookiecheck/start.html"
style="display:none" />
Run Code Online (Sandbox Code Playgroud)
客户端JS:
var receiveMessage = function (evt) {
if (evt.data === 'MM:3PCunsupported') {
document.getElementById('result').innerHTML = 'not supported';
} else if (evt.data === 'MM:3PCsupported') {
document.getElementById('result').innerHTML = 'supported';
}
};
window.addEventListener("message", receiveMessage, false);
Run Code Online (Sandbox Code Playgroud)
当然,这需要客户端运行JavaScript,这与基于服务器的解决方案相比是一个缺点; 另一方面,它更简单,你问的是JS解决方案.
Alan的解决方案很棒,但您不必使用PHP或任何其他服务器端编程语言.
至少如果你使用nginx.:)
这是Alan的解决方案的纯*nginx服务器端配置:
server {
listen 80;
server_name third-party.example.com
# don't allow user's browser to cache these replies
expires -1;
add_header Cache-Control "private";
etag off;
Run Code Online (Sandbox Code Playgroud)
location = /step1.js.php {
add_header Content-Type 'application/javascript; charset=UTF-8';
add_header Set-Cookie "third_party_c_t=hey there!;Max-Age=172800";
return 200 'window._3rd_party_test_step1_loaded();';
}
Run Code Online (Sandbox Code Playgroud)
location = /step2.js.php {
add_header Content-Type 'application/javascript; charset=UTF-8';
set $test 'false';
if ($cookie_third_party_c_t = 'hey there!') {
set $test 'true';
# clear the cookie
add_header Set-Cookie "third_party_c_t=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
return 200 'window._3rd_party_test_step2_loaded($test);';
}
Run Code Online (Sandbox Code Playgroud)
}
Run Code Online (Sandbox Code Playgroud)
附注:
third-party-cookies.html
)完全兼容,server
部分(范围) - 我保留了这种方式,以保持更多的"1:1"转换.理论上,您只需在某个地方调用一个页面来设置第三方 cookie,然后检查该 cookie 是否存在。然而,标准浏览器安全性不允许来自域 A 的脚本对域 B、C 等上设置的 cookie 执行任何操作...例如,您无法访问“外部”cookie。
如果您有一些特定的用途,例如检查广告是否被阻止(这也会阻止第 3 方跟踪 cookie),您可以检查广告服务器的内容是否在页面的 DOM 内,但您无法查看广告服务器的内容是否在页面的 DOM 内。饼干就在那里。