Cookie Change Events

Editor’s Draft,

This version:
https://patrickkettner.github.io/cookie-change-events
Issue Tracking:
GitHub
Editors:
(Microsoft)
(Microsoft)

Abstract

This specification describes an object based interface to cookies, and an API that can be used to attach events to cookie changes via javascript

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

This section is non-normative.

Web Applications have conventionally had to poll document.cookie in order to know when a cookie has been modified or removed. In order to improve performance and reduce the use of unnecessary timers, this specification describes an API that allows for web developers to attach an event listener to `document.cookie`, and receive the relevant information about a cookie change via a callback. As a side effect of defining the data about the individual cookie that has changed, this document also creates an object based interface for getting and setting `document.cookie` values

2. Definitions

dictionary CookieInit {
    USVString name;
    DOMString expires;
    long long maxAge;
    USVString domain;
    USVString path;
    boolean secure;
    required USVString value;
};

A CookieInit is a generic object that can be used to define a new cookie. You can set the following fields:

  • name is the key value in the key value pairing for cookies. Because of backwards compatibility, it is not required.
  • expires is an optional string value of a RFC 1123 Date, pursuant to RFC 6265§4.1.1
  • maxAge is an optional numeric value that, when specified, defines the number of seconds until the cookie expires, starting when the value is set, pursuant to RFC 6265§5.2.2
  • domain is an optional attribute that specifies what domain the cookie will be sent to, pursuant to RFC 6265§5.2.3.
  • path is an optional attribute that will only give access to the cookie if the requested resource matches the specified path, pursuant to RFC 6265§5.2.4.
  • secure is an optional boolean attribute that, when true, signals that the cookie can only be transmitted over "secure" protocols, as defined by the user agent. pursuant to RFC 6265§5.4, subsection 1
  • value is the only required attribute. It is a string, as defined as a cookie-value in RFC 6265
[Constructor((CookieInit or USVString) cookie), Exposed=Window]
interface Cookie {
    readonly attribute USVString name;
    attribute DOMString expires;
    attribute USVString value;
    readonly attribute USVString domain;
    readonly attribute USVString path;
    readonly attribute boolean secure;
    stringifier USVString ();
};

For backwards compatibility, the stringifier for a Cookie returns the serialized version of the object in a format that is consistent with how a cookie is returned on the original document.cookie. The Cookie can be set via a CookieInit object, or via the same serialized string.

[Exposed=Window]
interface CookieJar : EventTarget {
    stringifier attribute USVString value;
    maplike<USVString, Cookie>;
    attribute EventHandler onchange;
    setter USVString ((Cookie or USVString) cookie);
};

CookieJar represents all of the current cookies set on a domain, and is available via `document.cookie`.

  • value is a seralized version of the current valid cookies, in the same format as the historical value returns from `document.cookie`.
  • onchange is an event handler to listen for a `change` event (see: §3 the Change event)
partial interface Document {
    [PutForwards=value] attribute CookieJar cookie;
};

For backwards compatibility, a CookieJar, when accessed as document.cookie, returns the serialized string version of a Cookie. However, a iterator is also defined, which returns the object form of Cookie on each iteration.

let cookie = document.cookie
typeof cookie === 'string' // returns true

for (let cookie of document.cookie) {
  if (cookie.name === 'cookieIWantToDelete') {
    doucment.cookie.delete(cookie)
  }
}

3. the Change event

enum ChangeCause {
  "explicit",
  "evicted",
  "expired",
  "expired-overwrite",
  "overwrite",
  "created"
};

A ChangeCause is a string that represents the reason the cookie change event has been fired.

  • explicit is to be used when a delete() function has been called on a cookie called.
  • evicted is to be used when when a cookie has been automatically removed due to garbage collection.
  • expired is to be used when when a cookie’s max-age value expires, or when the expires value is in the past.
  • expired-overwrite is to be used when when a cookie’s max-age value is set to 0, or when the expires value is overwritten with a value in the past
  • overwrite is to be used when when a cookie’s value is overwritten.
  • created is to be used when when a cookie is created.
[Constructor(DOMString type, optional CookieChangeEventInit eventInitDict), Exposed=(Window)]
interface CookieChangeEventInit : Event {
    attribute boolean removed;
    attribute ChangeCause cause;
    attribute Cookie cookie;
};
interface CookieChangeEvent : Event {
  readonly attribute boolean removed;
  readonly attribute ChangeCause cause;
  readonly attribute Cookie cookie;
};

A CookieChangeEvent is an event that is fired when a ChangeCause has been triggered.

  • removed is a boolean that represents whether or not a cookie has been removed from the CookieJar
  • cause is a valid ChangeCause, representing why a cookie the cookie in question has been modified.
  • cookie is a valid Cookie, that represents the cookie that has been modified.

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WebIDL]
Cameron McCormack; Boris Zbarsky; Tobie Langel. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

IDL Index

dictionary CookieInit {
    USVString name;
    DOMString expires;
    long long maxAge;
    USVString domain;
    USVString path;
    boolean secure;
    required USVString value;
};

[Constructor((CookieInit or USVString) cookie), Exposed=Window]
interface Cookie {
    readonly attribute USVString name;
    attribute DOMString expires;
    attribute USVString value;
    readonly attribute USVString domain;
    readonly attribute USVString path;
    readonly attribute boolean secure;
    stringifier USVString ();
};

[Exposed=Window]
interface CookieJar : EventTarget {
    stringifier attribute USVString value;
    maplike<USVString, Cookie>;
    attribute EventHandler onchange;
    setter USVString ((Cookie or USVString) cookie);
};

partial interface Document {
    [PutForwards=value] attribute CookieJar cookie;
};

enum ChangeCause {
  "explicit",
  "evicted",
  "expired",
  "expired-overwrite",
  "overwrite",
  "created"
};

[Constructor(DOMString type, optional CookieChangeEventInit eventInitDict), Exposed=(Window)]
interface CookieChangeEventInit : Event {
    attribute boolean removed;
    attribute ChangeCause cause;
    attribute Cookie cookie;
};

interface CookieChangeEvent : Event {
  readonly attribute boolean removed;
  readonly attribute ChangeCause cause;
  readonly attribute Cookie cookie;
};