Техническая справка
Сторонние устанавливают и считывают файлы cookie по HTTP (не в JavaScript).
Поэтому нам необходимо два запроса к внешнему домену, чтобы проверить, включены ли сторонние файлы cookie:
- Тот, где третья сторона устанавливает cookie-файл (ы)
- Второй, с различным откликом в зависимости от того, отправил ли браузер куки-файлы обратно на тот же третийсторона во втором запросе.
Мы не можем использовать XMLHTTPRequest (Ajax) из-за модели безопасности DOM.
Очевидно, что вы не можете загрузить оба сценария параллельно или второй запросможет быть сделано до того, как ответ первого запроса вернет его, и тестовые файлы cookie не будут установлены.
Пример кода
Дано:
Файл .html
находится на одном домене, а
Файлы .js.php
находятся на втором домене, у нас есть:
Тестовая страница HTML
Сохранено как 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>
FПервый сторонний файл JavaScript
Сохранен как step1.js.php
Он написан на PHP, поэтому мы можем устанавливать куки при загрузке файла.(Конечно, он может быть написан на любом языке или даже выполнен в конфигурационных файлах сервера.)
<?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();
Второй сторонний файл JavaScript
Сохранен как step2.js.php
Это написано на PHP, поэтому мы можем читать куки на стороне сервера, прежде чем мы ответим.Мы также очищаем куки, чтобы тест можно было повторить (если вы хотите поработать с настройками браузера и повторить попытку).
<?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 без их разрешения. Они могут самопроизвольно ломаться или внедрять вредоносные программы. И это грубо.)