我有一个应用程序需要检查客户端浏览器是否启用了第三方cookie。有谁知道如何在JavaScript中执行此操作?
答案 0 :(得分:67)
第三方设置&通过HTTP(而不是JavaScript)读取cookie。
因此,我们需要两个外部域请求来测试是否启用了第三方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>
保存为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();
保存为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'); ?>);
最后一行使用三元运算符输出文字Javascript true
或false
,具体取决于测试Cookie是否存在。
可在https://alanhogan.github.io/web-experiments/3rd/third-party-cookies.html获得您的测试乐趣。
(最后一点 - 不要使用其他人的服务器在没有他们许可的情况下测试第三方cookie。它可能会自发破坏或注入恶意软件。而且这很粗鲁。)
答案 1 :(得分:41)
这是一个纯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" />
客户端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);
当然,这需要客户端运行JavaScript,这与基于服务器的解决方案相比是一个缺点;另一方面,它更简单,你问的是JS解决方案。
答案 2 :(得分:6)
Alan's solution很棒,但您不必使用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;
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();';
}
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);';
}
}
附注:
third-party-cookies.html
)完全兼容,server
部分(范围) - 我保持这种方式以保持更多“1:1 “翻译。答案 3 :(得分:1)
理论上,你只需要在某处设置一个页面调用,设置第三方cookie,然后检查该cookie是否存在。但是,标准浏览器安全性不允许域A的脚本对域B,C等上设置的cookie执行任何操作...你不能访问“外国”cookie。
如果您有一些特定用途,例如检查广告是否被屏蔽(这也会阻止第三方跟踪Cookie),您可以检查广告服务器的内容是否在网页的DOM中,但您不能看看那里是否有cookie。
答案 4 :(得分:1)
我的解决方案的工作原理是从设置cookie的外部域加载