Проверьте, включены ли сторонние куки - PullRequest
48 голосов
/ 23 августа 2010

У меня есть приложение, которое должно проверить, включены ли в браузере клиента сторонние файлы cookie. Кто-нибудь знает, как это сделать в JavaScript?

Ответы [ 4 ]

67 голосов
/ 18 августа 2011

Техническая справка

Сторонние устанавливают и считывают файлы cookie по HTTP (не в JavaScript).

Поэтому нам необходимо два запроса к внешнему домену, чтобы проверить, включены ли сторонние файлы cookie:

  1. Тот, где третья сторона устанавливает cookie-файл (ы)
  2. Второй, с различным откликом в зависимости от того, отправил ли браузер куки-файлы обратно на тот же третийсторона во втором запросе.

Мы не можем использовать XMLHTTPRequest (Ajax) из-за модели безопасности DOM.

Очевидно, что вы не можете загрузить оба сценария параллельно или второй запросможет быть сделано до того, как ответ первого запроса вернет его, и тестовые файлы cookie не будут установлены.

Пример кода

Дано:

  1. Файл .html находится на одном домене, а

  2. Файлы .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&hellip;';
  // 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&hellip;</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 без их разрешения. Они могут самопроизвольно ломаться или внедрять вредоносные программы. И это грубо.)

41 голосов
/ 25 января 2016

Вот чистое решение 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.

6 голосов
/ 06 марта 2015

Решение Алана отлично, но вам не нужно использовать PHP или любой другой серверный язык программирования.

По крайней мере, если вы используете nginx ,:)

Это чисто серверная конфигурация * nginx для решения Алана:

Запуск конфигурации 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;

Первый сторонний "файл JavaScript" -обслуживается nginx

    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();';
    }

Второй сторонний "файл JavaScript" - обслуживается nginx

    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);';
    }

Конец конфигурации Nginx

}

Примечания:

  • Да, да, я знаю, что IfIsEvil ,
  • Я сохранил имена, заканчивающиеся на ".php" дляполная совместимость с «Тестовой страницей HTML» Алана (third-party-cookies.html),
  • Вы также можете переместить общую строку «Установка заголовка Content-Type» обоих местоположений в раздел server (область действия)конфиг - я сохранил его таким образом, чтобы перевод был более "1: 1".
1 голос
/ 24 августа 2010

Теоретически, вам нужно просто вызвать страницу где-нибудь, которая установит сторонний файл cookie, а затем проверить его существование.Однако стандартная защита браузера не позволяет сценариям из домена A что-либо делать с файлами cookie, установленными в доменах B, C и т. Д., Например, вы не можете получить доступ к «чужим» файлам cookie.

Если вы имеете в виду какое-то конкретное использование, такое как проверка, не заблокированы ли объявления (что также заблокировало бы сторонний cookie-файл отслеживания), вы можете проверить, находится ли контент рекламного сервера в DOM страницы, ноне могу увидеть, есть ли там печенье.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...