patrickkettner / cookie-change-events

small extension to document.cookie that allows for event listeners
https://patrickkettner.github.io/cookie-change-events/
Other
22 stars 3 forks source link

what is the key for a keyless value? #22

Open patrickkettner opened 7 years ago

patrickkettner commented 7 years ago

document.cookie="foo" creates a keyless cookie. We need to define what happens when that value is put into the object form. Options I can think of would be...

  { '': 'foo' }
  { undefined: 'foo' }
  { null: 'foo' }

Feel like undefined is the correct path here, but would like to collect feedback before defining the behavior

bsittler commented 7 years ago

FYI, there is not complete cross-browser consensus on this - see https://inikulin.github.io/cookie-compat/ for the shocking results of @inikulin 's research into this (and many other) aspects of cookie interoperability

patrickkettner commented 7 years ago

thanks for the ref! I actualyl did check it out before the initial explainer. The question here was when given the object representation of a cookie (a Cookie, in the context of this spec), when someone set a cookie like so

`document.cookie="=foo", (which is valid...for some reason), should cookie.name be a string or not. The case against obviously being that strings are truthy, and given that a developer used that cookie for some reason, they may be keying off of that value being not truthy.

bsittler commented 7 years ago

That makes sense. If it were up to me I would use an empty string to avoid surprises, but none of the options here is particularly good.

patrickkettner commented 7 years ago

what surprises do you imagine encountering? Really interested in contrarian feedback, because literally ever web developer I have asked about this situation has heavily preferred undefined (and I want to make sure I am not in some kind of echo chamber).

bsittler commented 7 years ago

I believe existing cookie libraries - both server-side and client-side - that allow empty-name cookies of the form Set-Cookie: =value[; flags...] at all (as opposed to ignoring/discarding them) mostly treat the name as "" (empty string). I think that for this API to do something different would be surprising. Perhaps @FagnerMartinsBrack has more experience and insight here

FagnerMartinsBrack commented 7 years ago

I always refer to RFC 6265. It says the cookie-value can contain anything in a token which is:

OCTET = <any 8-bit sequence of data> CHAR = <any US-ASCII character (octets 0 - 127)> UPALPHA = <any US-ASCII uppercase letter "A".."Z"> LOALPHA = <any US-ASCII lowercase letter "a".."z"> ALPHA = UPALPHA | LOALPHA DIGIT = <any US-ASCII digit "0".."9"> CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> CR = <US-ASCII CR, carriage return (13)> LF = <US-ASCII LF, linefeed (10)> SP = <US-ASCII SP, space (32)> HT = <US-ASCII HT, horizontal-tab (9)> <"> = <US-ASCII double-quote mark (34)>

It says it can contain control characters. However, it doesn't say it's optional or that it can be empty. Therefore, I would argue one should not let the user create a cookie with an empty cookie-name because that's not allowed, or if let them do so, then it's an undefined behavior.

js-cookie have never received any report of someone setting the key as empty and having an astonishing result or complaining about interoperability. By looking at the code, it looks like js-cookie will not validate and will just set document.cookie = '=value' if an empty key is provided. The behavior there is undefined, until someone complains about it.

I don't know if there are additional implications on having an empty string. Maybe asking for the ones who wrote the spec at the time?

patrickkettner commented 7 years ago

Therefore, I would argue one should not let the user create a cookie with an empty cookie-name because that's not allowed, or if let them do so, then it's an undefined behavior.

You can today, and therefore I can't stop someone from settings those values.

document.cookie="=foo" and document.cookie="bar" both set cookies in every browser I can get my hands on, and in a consistent way. I totally understand that it is an edge case, but it is a case that the IDL has to be able to represent, lest we have incompatible implementations for a problem we could see beforehand.

bsittler commented 7 years ago

Does "every browser I can get my hands on" exclude Safari?

I believe that in Safari "=foo" is ignored and "bar" is equivalent to "bar=", whereas in Firefox, IE, Edge and Chrome "=foo" is setting the cookie whose name is "" and "bar" is too, since it's equivalent to "=bar".

patrickkettner commented 7 years ago

you are correct