Kann ich über Cookie-Änderungen im clientseitigen Javascript benachrichtigt werden?

Lesezeit: 4 Minuten

Benutzer-Avatar
pm100

Kann ich irgendwie Änderungen an Cookies (für meine Domain) in meinem clientseitigen Javascript verfolgen. Zum Beispiel eine Funktion, die aufgerufen wird, wenn ein Cookie geändert, gelöscht oder hinzugefügt wird

In der Reihenfolge der Präferenz

  • Standard-Cross-Browser
  • Cross-Browser
  • browserspezifisch
  • Erweiterung / Plugin

Wieso den? weil Cookies, auf die ich in Fenster/Tab Nr. 1 angewiesen bin, in Fenster/Tab Nr. 2 geändert werden können.

Ich habe herausgefunden, dass Chrome Erweiterungen ermöglicht, über Änderungen an Cookies benachrichtigt zu werden. Aber das ist meine unbeliebteste Option

  • Cookies können keine Kommunikation zu ihrer jeweiligen Webseite initiieren. Es liegt in der Verantwortung der Webseite, den Inhalt von Cookies zu verfolgen.

    – Srijan

    15. Januar 2013 um 18:31 Uhr

Benutzer-Avatar
fuweichin

Methode 1: Regelmäßige Abfrage

Umfrage document.cookie

function listenCookieChange(callback, interval = 1000) {
  let lastCookie = document.cookie;
  setInterval(()=> {
    let cookie = document.cookie;
    if (cookie !== lastCookie) {
      try {
        callback({oldValue: lastCookie, newValue: cookie});
      } finally {
        lastCookie = cookie;
      }
    }
  }, interval);
}

Verwendungszweck

listenCookieChange(({oldValue, newValue})=> {
  console.log(`Cookie changed from "${oldValue}" to "${newValue}"`);
}, 1000);

document.cookie="a=1";

Methode 2: API-Abfangen

Abfangen document.cookie

(()=> {
  let lastCookie = document.cookie;
  // rename document.cookie to document._cookie, and redefine document.cookie
  const expando = '_cookie';
  let nativeCookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
  Object.defineProperty(Document.prototype, expando, nativeCookieDesc);
  Object.defineProperty(Document.prototype, 'cookie', {
    enumerable: true,
    configurable: true,
    get() {
      return this[expando];
    },
    set(value) {
      this[expando] = value;
      // check cookie change
      let cookie = this[expando];
      if (cookie !== lastCookie) {
        try {
          // dispatch cookie-change messages to other same-origin tabs/frames
          let detail = {oldValue: lastCookie, newValue: cookie};
          this.dispatchEvent(new CustomEvent('cookiechange', {
            detail: detail
          }));
          channel.postMessage(detail);
        } finally {
          lastCookie = cookie;
        }
      }
    }
  });
  // listen cookie-change messages from other same-origin tabs/frames
  const channel = new BroadcastChannel('cookie-channel');
  channel.onmessage = (e)=> {
    lastCookie = e.data.newValue;
    document.dispatchEvent(new CustomEvent('cookiechange', {
      detail: e.data
    }));
  };
})();

Verwendungszweck

document.addEventListener('cookiechange', ({detail: {oldValue, newValue}})=> {
  console.log(`Cookie changed from "${oldValue}" to "${newValue}"`);
});

document.cookie="a=1";

Anmerkungen

  1. nicht für IE
  2. erfordern BroadcastChannel Polyfill für Safari

Fazit

| Metric \ Method  | Periodic Polling            | API Interception |
| ---------------- | --------------------------- | ---------------- |
| delay            | depends on polling interval | instant          |
| scope            | same-domain                 | same-origin      |

  • Funktioniert dies nur für mich, wenn die Cookies in der Browserkonsole gesetzt sind, aber nicht, wenn das Cookie durch einen Set-Cookie-Antwortheader gesetzt wird

    – Dashiell Rose Bark-Huss

    27. Dezember 2020 um 0:10 Uhr

  • Es gibt eine experimentelle Cookie Store API mit vollem Funktionsumfang, wigg.github.io/cookie-store/#example-1ce710fe

    – fuweichin

    13. Januar 2021 um 10:11 Uhr

  • Leider scheint die Cookie Store API derzeit nicht vollständig browserübergreifend zu sein.

    – Elixon

    7. Januar um 17:22 Uhr

  • scheint meine einzige tragbare Option zu sein

    – pm100

    15. Januar 2013 um 23:11 Uhr

  • Es scheint, als könnte dies bald eine Sache sein? developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/…

    – Würdig7

    10. April 2019 um 1:20 Uhr

  • @Worthy7 Das sieht aus wie eine API für Browsererweiterungen, nicht für Websites

    – Alice Purcell

    17. Juni 2019 um 16:34 Uhr

  • sollte es nicht window.setInterval(checkCookie(), 100) sein;

    – d7my

    17. März 2021 um 15:27 Uhr

  • @d7my checkCookie wird sofort aufgerufen, wenn es instanziiert wird, und gibt ein fn zurück, also nein, Sie müssen es nicht in der aufrufen setInterval

    – Benjamin

    1. April 2021 um 13:24 Uhr

Wenn Sie die neue verwenden möchten CookieStore und die Unterstützung aller Browser wünschen, können Sie ein (spekulatives) Polyfill wie folgt installieren: https://github.com/markcellus/cookie-store

Benutzer-Avatar
iamousseni

Ich denke, mein Weg ist besser. Ich habe ein benutzerdefiniertes Ereignis geschrieben, um zu erkennen, wann ein Cookie zufällig ist:

const cookieEvent = new CustomEvent("cookieChanged", {
  bubbles: true,
  detail: {
    cookieValue: document.cookie,
    checkChange: () => {
      if (cookieEvent.detail.cookieValue != document.cookie) {
        cookieEvent.detail.cookieValue = document.cookie;
        return 1;
      } else {
        return 0;
      }
    },
    listenCheckChange: () => {
      setInterval(function () {
        if (cookieEvent.detail.checkChange() == 1) {
          cookieEvent.detail.changed = true;
          //fire the event
          cookieEvent.target.dispatchEvent(cookieEvent);
        } else {
          cookieEvent.detail.changed = false;
        }
      }, 1000);
    },
    changed: false
  }
});

/*FIRE cookieEvent EVENT WHEN THE PAGE IS LOADED TO
 CHECK IF USER CHANGED THE COOKIE VALUE */

document.addEventListener("DOMContentLoaded", function (e) {
  e.target.dispatchEvent(cookieEvent);
});

document.addEventListener("cookieChanged", function (e) {
  e.detail.listenCheckChange();
  if(e.detail.changed === true ){
    /*YOUR CODE HERE FOR DO SOMETHING 
      WHEN USER CHANGED THE COOKIE VALUE */
  }
});

Benutzer-Avatar
Mosche L

Wenn der Code, der die Cookies manipuliert hat, Ihnen gehört, können Sie verwenden localStorage für die Nachverfolgung mit Ereignissen geändert. Beispielsweise können Sie einen Müll auf dem localStorage speichern, um ein Ereignis auf den anderen Registerkarten auszulösen.

zum Beispiel

var checkCookie = function() {

var lastCookies = document.cookie.split( ';' ).map( function( x ) { return x.trim().split( /(=)/ ); } ).reduce( function( a, b ) { 
        a[ b[ 0 ] ] = a[ b[ 0 ] ] ? a[ b[ 0 ] ] + ', ' + b.slice( 2 ).join( '' ) :  
        b.slice( 2 ).join( '' ); return a; }, {} );


return function() {

    var currentCookies =  document.cookie.split( ';' ).map( function( x ) { return x.trim().split( /(=)/ ); } ).reduce( function( a, b ) { 
        a[ b[ 0 ] ] = a[ b[ 0 ] ] ? a[ b[ 0 ] ] + ', ' + b.slice( 2 ).join( '' ) :  
        b.slice( 2 ).join( '' ); return a; }, {} );


    for(cookie in currentCookies) {
        if  ( currentCookies[cookie] != lastCookies[cookie] ) {
            console.log("--------")
            console.log(cookie+"="+lastCookies[cookie])
            console.log(cookie+"="+currentCookies[cookie])
        }

    }
    lastCookies = currentCookies;

};
}();
 $(window).on("storage",checkCookie); // via jQuery. can be used also with VanillaJS


// on the function changed the cookies

document.cookie = ....
window.localStorage["1"] = new Date().getTime(); // this will trigger the "storage" event in the other tabs.

  • Das ist sehr interessant – die Verwendung von localStorage als Kommunikationsmechanismus zwischen Browserfenstern, die für dieselbe “App” geöffnet sind

    – pm100

    31. Mai 2018 um 21:34 Uhr

1009980cookie-checkKann ich über Cookie-Änderungen im clientseitigen Javascript benachrichtigt werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy