Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #39753 > unrolled thread

Create cookie from ID of <a> tag

Started byDaniele Ferrarese <daniele.seversrl@gmail.com>
First post2021-03-24 09:36 -0700
Last post2021-03-28 06:26 -0700
Articles 20 on this page of 24 — 8 participants

Back to article view | Back to comp.lang.javascript


Contents

  Create cookie from ID of <a> tag Daniele Ferrarese <daniele.seversrl@gmail.com> - 2021-03-24 09:36 -0700
    Re: Create cookie from ID of <a> tag The Natural Philosopher <tnp@invalid.invalid> - 2021-03-24 17:54 +0000
      Re: Create cookie from ID of <a> tag Daniele Ferrarese <daniele.seversrl@gmail.com> - 2021-03-25 01:05 -0700
        Re: Create cookie from ID of <a> tag The Natural Philosopher <tnp@invalid.invalid> - 2021-03-25 09:13 +0000
          Re: Create cookie from ID of <a> tag Daniele Ferrarese <daniele.seversrl@gmail.com> - 2021-03-25 02:21 -0700
            Re: Create cookie from ID of <a> tag Daniele Ferrarese <daniele.seversrl@gmail.com> - 2021-03-25 03:23 -0700
              Re: Create cookie from ID of <a> tag Daniele <webmaster@appliserver.com> - 2021-03-26 09:19 +0100
                Re: Create cookie from ID of <a> tag Daniele Ferrarese <daniele.seversrl@gmail.com> - 2021-03-26 01:57 -0700
                Re: Create cookie from ID of <a> tag Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-03-26 17:33 +0100
                  Re: Create cookie from ID of <a> tag Jon Ribbens <jon+usenet@unequivocal.eu> - 2021-03-26 17:20 +0000
                    Re: Create cookie from ID of <a> tag Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-03-26 19:35 +0100
                      Re: Create cookie from ID of <a> tag Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-03-26 23:22 +0100
                        Re: Create cookie from ID of <a> tag "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2021-03-26 15:39 -0700
                          Re: Create cookie from ID of <a> tag Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-03-31 00:58 +0200
                            Re: Create cookie from ID of <a> tag "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2021-03-30 19:58 -0700
                              Re: Create cookie from ID of <a> tag Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-04-01 10:09 +0200
                                Re: Create cookie from ID of <a> tag "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2021-04-01 06:11 -0700
                                  Re: Create cookie from ID of <a> tag Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2021-04-01 19:34 +0200
                Re: Create cookie from ID of <a> tag The Natural Philosopher <tnp@invalid.invalid> - 2021-03-26 17:10 +0000
                  Re: Create cookie from ID of <a> tag Daniele <webmaster@appliserver.com> - 2021-03-27 12:16 +0100
                    Re: Create cookie from ID of <a> tag The Natural Philosopher <tnp@invalid.invalid> - 2021-03-27 13:25 +0000
                    Re: Create cookie from ID of <a> tag "Mark-" <nospam@mapson.xyz> - 2021-03-31 13:26 +0000
                Re: Create cookie from ID of <a> tag Daniele <webmaster@appliserver.com> - 2021-03-27 12:08 +0100
    Re: Create cookie from ID of <a> tag Man From a city with name Viljandi <ya12983@mail.com> - 2021-03-28 06:26 -0700

Page 1 of 2  [1] 2  Next page →


#39753 — Create cookie from ID of <a> tag

FromDaniele Ferrarese <daniele.seversrl@gmail.com>
Date2021-03-24 09:36 -0700
SubjectCreate cookie from ID of <a> tag
Message-ID<06c15260-54cb-43fd-99f0-cba71b0caa36n@googlegroups.com>
Hello, I'm a beginner with js. I was wondering if it was possible to create a cookie by taking the value from the ID of the <a> tag.
Thanks for your help.

Rgds Daniele

[toc] | [next] | [standalone]


#39756

FromThe Natural Philosopher <tnp@invalid.invalid>
Date2021-03-24 17:54 +0000
Message-ID<s3fudf$eg3$1@dont-email.me>
In reply to#39753
On 24/03/2021 16:36, Daniele Ferrarese wrote:
> Hello, I'm a beginner with js. I was wondering if it was possible to create a cookie by taking the value from the ID of the <a> tag.
> Thanks for your help.
> 
> Rgds Daniele
> 
Normally cookies are set by the server and stored on the client, but 
javascript can set a cookie independently of that:

https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie

I am not clear on what the 'id of the A tag' actually means.

Do you mean there is something like <a href=" blah.com" 
id="uttercrap">cobblers</a>  and you want to set a cookie to 'uttercrap'

The problem is how will you know which <a></a> element to refer to, 
unless you *already* know its id?


-- 
A lie can travel halfway around the world while the truth is putting on 
its shoes.

[toc] | [prev] | [next] | [standalone]


#39762

FromDaniele Ferrarese <daniele.seversrl@gmail.com>
Date2021-03-25 01:05 -0700
Message-ID<01863a61-d1bf-47ec-9955-1a1579e9aca2n@googlegroups.com>
In reply to#39756
Il giorno mercoledì 24 marzo 2021 alle 18:55:02 UTC+1 The Natural Philosopher ha scritto:
> On 24/03/2021 16:36, Daniele Ferrarese wrote: 
> > Hello, I'm a beginner with js. I was wondering if it was possible to create a cookie by taking the value from the ID of the <a> tag. 
> > Thanks for your help. 
> > 
> > Rgds Daniele 
> >
> Normally cookies are set by the server and stored on the client, but 
> javascript can set a cookie independently of that: 
> 
> https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie 
> 
> I am not clear on what the 'id of the A tag' actually means. 
> 
> Do you mean there is something like <a href=" blah.com" 
> id="uttercrap">cobblers</a> and you want to set a cookie to 'uttercrap' 
> 
> The problem is how will you know which <a></a> element to refer to, 
> unless you *already* know its id? 
> 
> 
> -- 
> A lie can travel halfway around the world while the truth is putting on 
> its shoes.
----------------------------------------------
I thank you for your kind reply. You understood perfectly. The <a> element is the calling element therefore is calling itself.
How it can call itself and create a cookie with "value" its ID? Something like this ?
<a href="javascript: var x = this.id; document.cookie="language="+x"";></a>
Of course I tried this solution but is not running.
Form will submit this value to server and response will update all texts in corresponsing language.

Can you tell me where is the mistake.
Thanks again for your help.

Rgds - Daniele

[toc] | [prev] | [next] | [standalone]


#39763

FromThe Natural Philosopher <tnp@invalid.invalid>
Date2021-03-25 09:13 +0000
Message-ID<s3hk8a$g7n$1@dont-email.me>
In reply to#39762
On 25/03/2021 08:05, Daniele Ferrarese wrote:
> Il giorno mercoledì 24 marzo 2021 alle 18:55:02 UTC+1 The Natural Philosopher ha scritto:
>> On 24/03/2021 16:36, Daniele Ferrarese wrote:
>>> Hello, I'm a beginner with js. I was wondering if it was possible to create a cookie by taking the value from the ID of the <a> tag.
>>> Thanks for your help.
>>>
>>> Rgds Daniele
>>>
>> Normally cookies are set by the server and stored on the client, but
>> javascript can set a cookie independently of that:
>>
>> https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
>>
>> I am not clear on what the 'id of the A tag' actually means.
>>
>> Do you mean there is something like <a href=" blah.com"
>> id="uttercrap">cobblers</a> and you want to set a cookie to 'uttercrap'
>>
>> The problem is how will you know which <a></a> element to refer to,
>> unless you *already* know its id?
>>
>>
>> -- 
>> A lie can travel halfway around the world while the truth is putting on
>> its shoes.
> ----------------------------------------------
> I thank you for your kind reply. You understood perfectly. The <a> element is the calling element therefore is calling itself.
> How it can call itself and create a cookie with "value" its ID? Something like this ?
> <a href="javascript: var x = this.id; document.cookie="language="+x"";></a>
> Of course I tried this solution but is not running.
> Form will submit this value to server and response will update all texts in corresponsing language.
> 
> Can you tell me where is the mistake.

OK

Why are you using an <A> element just to set a cookie?
Do you actually want to reload the web page after setting a cookie?

Anyway no matter whether is an <a> element or any other element that you 
want the user to click on, what you need is an onclick=" statement

so

onclick="document.cookie='language='+this.id".

If you want to call the same web page again with this cookie set, then

<a href="#" onclick="document.cookie='language='+this.id; 
window.location.reload(true)" > My Language</a>

should work with all browsers. And it doesn't have to be in an 
<a>element</a>, since the reload is being done by javascript

So
<div onclick="document.cookie='language='+this.id; 
window.location.reload(true)"> click here to set cookie and reload 
page</div>

should work just as well


> 


-- 
"Anyone who believes that the laws of physics are mere social 
conventions is invited to try transgressing those conventions from the 
windows of my apartment. (I live on the twenty-first floor.) "

Alan Sokal

[toc] | [prev] | [next] | [standalone]


#39764

FromDaniele Ferrarese <daniele.seversrl@gmail.com>
Date2021-03-25 02:21 -0700
Message-ID<48e39d8c-ec2d-4759-8ddd-8ac063e510c3n@googlegroups.com>
In reply to#39763
Il giorno giovedì 25 marzo 2021 alle 10:13:52 UTC+1 The Natural Philosopher ha scritto:
> On 25/03/2021 08:05, Daniele Ferrarese wrote: 
> > Il giorno mercoledì 24 marzo 2021 alle 18:55:02 UTC+1 The Natural Philosopher ha scritto: 
> >> On 24/03/2021 16:36, Daniele Ferrarese wrote: 
> >>> Hello, I'm a beginner with js. I was wondering if it was possible to create a cookie by taking the value from the ID of the <a> tag. 
> >>> Thanks for your help. 
> >>> 
> >>> Rgds Daniele 
> >>> 
> >> Normally cookies are set by the server and stored on the client, but 
> >> javascript can set a cookie independently of that: 
> >> 
> >> https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie 
> >> 
> >> I am not clear on what the 'id of the A tag' actually means. 
> >> 
> >> Do you mean there is something like <a href=" blah.com" 
> >> id="uttercrap">cobblers</a> and you want to set a cookie to 'uttercrap' 
> >> 
> >> The problem is how will you know which <a></a> element to refer to, 
> >> unless you *already* know its id? 
> >> 
> >> 
> >> -- 
> >> A lie can travel halfway around the world while the truth is putting on 
> >> its shoes. 
> > ---------------------------------------------- 
> > I thank you for your kind reply. You understood perfectly. The <a> element is the calling element therefore is calling itself. 
> > How it can call itself and create a cookie with "value" its ID? Something like this ? 
> > <a href="javascript: var x = this.id; document.cookie="language="+x"";></a> 
> > Of course I tried this solution but is not running. 
> > Form will submit this value to server and response will update all texts in corresponsing language. 
> > 
> > Can you tell me where is the mistake.
> OK 
> 
> Why are you using an <A> element just to set a cookie? 
> Do you actually want to reload the web page after setting a cookie? 
> 
> Anyway no matter whether is an <a> element or any other element that you 
> want the user to click on, what you need is an onclick=" statement 
> 
> so 
> 
> onclick="document.cookie='language='+this.id". 
> 
> If you want to call the same web page again with this cookie set, then 
> 
> <a href="#" onclick="document.cookie='language='+this.id; 
> window.location.reload(true)" > My Language</a> 
> 
> should work with all browsers. And it doesn't have to be in an 
> <a>element</a>, since the reload is being done by javascript 
> 
> So 
> <div onclick="document.cookie='language='+this.id; 
> window.location.reload(true)"> click here to set cookie and reload 
> page</div> 
> 
> should work just as well 
> 
> 
> > 
> 
> 
> -- 
> "Anyone who believes that the laws of physics are mere social 
> conventions is invited to try transgressing those conventions from the 
> windows of my apartment. (I live on the twenty-first floor.) " 
> 
> Alan Sokal

Thanks for your reply and help. 
In effect I want to reload the same page with all texts in the selected language coming from db.
I'll try later. 
Thanks again.

[toc] | [prev] | [next] | [standalone]


#39765

FromDaniele Ferrarese <daniele.seversrl@gmail.com>
Date2021-03-25 03:23 -0700
Message-ID<cca12429-db8b-4747-990f-0f9e2fedba5dn@googlegroups.com>
In reply to#39764
Il giorno giovedì 25 marzo 2021 alle 10:21:47 UTC+1 Daniele Ferrarese ha scritto:
> Il giorno giovedì 25 marzo 2021 alle 10:13:52 UTC+1 The Natural Philosopher ha scritto: 
> > On 25/03/2021 08:05, Daniele Ferrarese wrote: 
> > > Il giorno mercoledì 24 marzo 2021 alle 18:55:02 UTC+1 The Natural Philosopher ha scritto: 
> > >> On 24/03/2021 16:36, Daniele Ferrarese wrote: 
> > >>> Hello, I'm a beginner with js. I was wondering if it was possible to create a cookie by taking the value from the ID of the <a> tag. 
> > >>> Thanks for your help. 
> > >>> 
> > >>> Rgds Daniele 
> > >>> 
> > >> Normally cookies are set by the server and stored on the client, but 
> > >> javascript can set a cookie independently of that: 
> > >> 
> > >> https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie 
> > >> 
> > >> I am not clear on what the 'id of the A tag' actually means. 
> > >> 
> > >> Do you mean there is something like <a href=" blah.com" 
> > >> id="uttercrap">cobblers</a> and you want to set a cookie to 'uttercrap' 
> > >> 
> > >> The problem is how will you know which <a></a> element to refer to, 
> > >> unless you *already* know its id? 
> > >> 
> > >> 
> > >> -- 
> > >> A lie can travel halfway around the world while the truth is putting on 
> > >> its shoes. 
> > > ---------------------------------------------- 
> > > I thank you for your kind reply. You understood perfectly. The <a> element is the calling element therefore is calling itself. 
> > > How it can call itself and create a cookie with "value" its ID? Something like this ? 
> > > <a href="javascript: var x = this.id; document.cookie="language="+x"";></a> 
> > > Of course I tried this solution but is not running. 
> > > Form will submit this value to server and response will update all texts in corresponsing language. 
> > > 
> > > Can you tell me where is the mistake. 
> > OK 
> > 
> > Why are you using an <A> element just to set a cookie? 
> > Do you actually want to reload the web page after setting a cookie? 
> > 
> > Anyway no matter whether is an <a> element or any other element that you 
> > want the user to click on, what you need is an onclick=" statement 
> > 
> > so 
> > 
> > onclick="document.cookie='language='+this.id". 
> > 
> > If you want to call the same web page again with this cookie set, then 
> > 
> > <a href="#" onclick="document.cookie='language='+this.id; 
> > window.location.reload(true)" > My Language</a> 
> > 
> > should work with all browsers. And it doesn't have to be in an 
> > <a>element</a>, since the reload is being done by javascript 
> > 
> > So 
> > <div onclick="document.cookie='language='+this.id; 
> > window.location.reload(true)"> click here to set cookie and reload 
> > page</div> 
> > 
> > should work just as well 
> > 
> > 
> > > 
> > 
> > 
> > -- 
> > "Anyone who believes that the laws of physics are mere social 
> > conventions is invited to try transgressing those conventions from the 
> > windows of my apartment. (I live on the twenty-first floor.) " 
> > 
> > Alan Sokal
> Thanks for your reply and help. 
> In effect I want to reload the same page with all texts in the selected language coming from db. 
> I'll try later. 
> Thanks again.
Everything is running perfectly.
Many thanks for your help.
Wish you a nice day.
Rgds
Daniele

[toc] | [prev] | [next] | [standalone]


#39768

FromDaniele <webmaster@appliserver.com>
Date2021-03-26 09:19 +0100
Message-ID<s3k5e5$aot$1@dont-email.me>
In reply to#39765
Il 25/03/2021 11:23, Daniele Ferrarese ha scritto:

> Everything is running perfectly.
> Many thanks for your help.
> Wish you a nice day.
> Rgds
> Daniele
> 

Hi, this is the code I use to manage cookies:

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

HTH,
Dan

[toc] | [prev] | [next] | [standalone]


#39774

FromDaniele Ferrarese <daniele.seversrl@gmail.com>
Date2021-03-26 01:57 -0700
Message-ID<805198bc-73f9-47b4-a06a-017627521634n@googlegroups.com>
In reply to#39768
Il giorno venerdì 26 marzo 2021 alle 09:19:25 UTC+1 Daniele ha scritto:
> Il 25/03/2021 11:23, Daniele Ferrarese ha scritto: 
> 
> > Everything is running perfectly. 
> > Many thanks for your help. 
> > Wish you a nice day. 
> > Rgds 
> > Daniele 
> >
> Hi, this is the code I use to manage cookies: 
> 
> function createCookie(name,value,days) { 
> if (days) { 
> var date = new Date(); 
> date.setTime(date.getTime()+(days*24*60*60*1000)); 
> var expires = "; expires="+date.toGMTString(); 
> } 
> else var expires = ""; 
> document.cookie = name+"="+value+expires+"; path=/"; 
> } 
> 
> function readCookie(name) { 
> var nameEQ = name + "="; 
> var ca = document.cookie.split(';'); 
> for(var i=0;i < ca.length;i++) { 
> var c = ca[i]; 
> while (c.charAt(0)==' ') c = c.substring(1,c.length); 
> if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); 
> } 
> return null; 
> } 
> 
> function eraseCookie(name) { 
> createCookie(name,"",-1); 
> } 
> 
> HTH, 
> Dan
Good morning Dan
Thank you very much for your kind help.
Wish you a nice day and nice weekend.

Daniele

[toc] | [prev] | [next] | [standalone]


#39776

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2021-03-26 17:33 +0100
Message-ID<2578953.mvXUDI8C0e@PointedEars.de>
In reply to#39768
Daniele wrote:
^^^^^^^
Please post using your real name (first name and last name suffice).

> Hi, this is the code I use to manage cookies:
> 
> function createCookie(name,value,days) {
> if (days) {
> var date = new Date();
> date.setTime(date.getTime()+(days*24*60*60*1000));

As we know the number of (milli)seconds per standard day,

  … + days * 864e5

would be more efficient (if this way of moving a date value forward one day 
would be safe).

> function readCookie(name) {
>   var nameEQ = name + "=";
>   var ca = document.cookie.split(';');
>   for(var i=0;i < ca.length;i++) {

    [“for” is not a function.  Do not write it as if it were.]

    for (var i = 0, len = ca.length; i < len; ++i) {

>     var c = ca[i];
>     while (c.charAt(0)==' ') c = c.substring(1,c.length);

Ouch.

  c = c.replace(/^ +/, '');

>     if (c.indexOf(nameEQ) == 0) return 
c.substring(nameEQ.length,c.length);

The argument c.length is superfluous.

>   }
>   return null;

 The return value on failure should be “undefined” instead because the 
function returns a primitive (String) value, not an object value, if 
successful.

> }

That is *very* inefficient and error-prone.  Consider this:

  function readCookie (name)
  {
    return (
      (
        document.cookie.split(';')
          .map((cookie) => cookie.split('='))
          .filter((cookie) => cookie[0] == name) || []
      )[0] || []
    )[1];
  }

    [without .filter(), this is useful as an approach to obtain *all*
     cookies in an easily processible data structure],

or

  function readCookie (name)
  {
    /* 
     * NOTE: Cookie names typically do not contain
     * RegExp special characters; otherwise those
     * need to be escaped.
     */
    return (document.cookie
      .match(new RegExp('(?:^|;)' + name + '=([^;]+)')) || [])[1];
  }
  
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#39778

FromJon Ribbens <jon+usenet@unequivocal.eu>
Date2021-03-26 17:20 +0000
Message-ID<slrns5s5ue.49m.jon+usenet@raven.unequivocal.eu>
In reply to#39776
On 2021-03-26, Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote:
> That is *very* inefficient and error-prone.  Consider this:
>
>   function readCookie (name)
>   {
>     return (
>       (
>         document.cookie.split(';')
>           .map((cookie) => cookie.split('='))
>           .filter((cookie) => cookie[0] == name) || []
>       )[0] || []
>     )[1];
>   }

Bear in mind this will fail on cookies whose values contain an '='.
In Python this is trivial to solve by using split('=', 1) but
unfortunately in JavaScript the limit parameter is almost useless.

[toc] | [prev] | [next] | [standalone]


#39779

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2021-03-26 19:35 +0100
Message-ID<4641170.31r3eYUQgx@PointedEars.de>
In reply to#39778
Jon Ribbens wrote:

> On 2021-03-26, Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote:
>> That is *very* inefficient and error-prone.  Consider this:
>>
>>   function readCookie (name)
>>   {
>>     return (
>>       (
>>         document.cookie.split(';')
>>           .map((cookie) => cookie.split('='))
>>           .filter((cookie) => cookie[0] == name) || []
>>       )[0] || []
>>     )[1];
>>   }
> 
> Bear in mind this will fail on cookies whose values contain an '='.

It will NOT fail, but it will return an incomplete value.

It is possible indeed for a read cookie value to contain an unescaped “=” 
character:

  document.cookie = 'foo=bar=baz';

creates a session cookie with the name “foo” and the value “bar=baz”, and 
after that “document.cookie” contains the substring “bar=baz” unescaped (in 
Chromium).

Thank you for pointing that out.

It is recommended to use the encodeURIComponent() function on the value to 
compatibly avoid storing this and other problematic/forbidden cookie values:

  document.cookie = 'foo=' + encodeURIComponent('bar=baz');

stores the value “bar%3Dbaz”.

Correspondingly, decodeURIComponent() should be used then when reading 
cookie values:

<https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie>

> In Python this is trivial to solve by using split('=', 1) but
> unfortunately in JavaScript the limit parameter is almost useless.

It is true that it cannot be simply used for this:

<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split>

The problem can still be solved simply by splitting on '=', but joining the 
remaining array elements:

  function readCookie (name)
  {
    return (
      (
        document.cookie.split(';')
          .map((cookie) => cookie.split('='))
          .filter((cookie) => cookie[0] == name) || []
      )[0] || []
    ).slice(1).join('=');
  }

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#39780

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2021-03-26 23:22 +0100
Message-ID<2196370.ElGaqSPkdT@PointedEars.de>
In reply to#39779
Thomas 'PointedEars' Lahn wrote:

> Jon Ribbens wrote:
>> On 2021-03-26, Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote:
>>> That is *very* inefficient and error-prone.  Consider this:
>>>
>>>   function readCookie (name)
>>>   {
>>>     return (
>>>       (
>>>         document.cookie.split(';')
>>>           .map((cookie) => cookie.split('='))
>>>           .filter((cookie) => cookie[0] == name) || []
>>>       )[0] || []
>>>     )[1];
>>>   }
>> 
>> Bear in mind this will fail on cookies whose values contain an '='.
> 
> It will NOT fail, but it will return an incomplete value.
> 
> It is possible indeed for a read cookie value to contain an unescaped “=”
> character:
> 
>   document.cookie = 'foo=bar=baz';
> 
> creates a session cookie with the name “foo” and the value “bar=baz”, and
> after that “document.cookie” contains the substring “bar=baz” unescaped
> (in Chromium).
> 
> Thank you for pointing that out.
> 
> It is recommended to use the encodeURIComponent() function on the value to
> compatibly avoid storing this and other problematic/forbidden cookie
> values:
> 
>   document.cookie = 'foo=' + encodeURIComponent('bar=baz');
> 
> stores the value “bar%3Dbaz”.
>  
> Correspondingly, decodeURIComponent() should be used then when reading
> cookie values:
> 
> <https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie>

This was poorly worded.  I mean: It is recommended to use 
encodeURIComponent() to allow storing cookie values that would otherwise not 
be able to be stored, for example values containing “;”; this *also* avoids 
the problem of dealing with “=” because then there are no unescaped “=” in 
cookie values, and the escaped “=” do not have to be treated differently 
than the other escaped characters.

It actually appears to be *necessary* to not simply split on “;”, but 
consider whitespace after “;”, so a RegExp SHOULD be used for 
splitting/matching.


As I keep thinking about this, one would hope that after all this time that 
cookies have been around, and given my impression that cookies are not going 
away anytime soon, a standard DOM attribute and built-in property will 
finally be introduced to make dealing with cookies easier and less error-
prone.

I would suggest

  document.cookies

for that.  The Web IDL¹ for it could be (similar to the Storage interface²)

  [Exposed=Document]
  interface mixin DocumentStorage {
    readonly attribute Cookies cookies;
  }

  [Exposed=DocumentStorage]
  interface Cookies {
    readonly attribute unsigned long length;
    DOMString? name(unsigned long index);
    sequence <DOMString> names();
    sequence <DOMString> values();
    sequence <record <DOMString, CookieAttributes>> items();
    getter DOMString? getItem(DOMString name);
    boolean hasItem(DOMString name);
    setter boolean setItem(DOMString name, DOMString value);
    setter boolean setItem(DOMString name, CookieAttributes attributes);
    deleter boolean removeItem(DOMString name);
    boolean clear();
  }

  dictionary CookieAttributes {
    required DOMString value;
    DOMString path = Location::pathname;
    unsigned long? maxAge = null;  /* default: end of session */

    /* or unsigned long, but Date would be more convenient */
    Date? expires = null;  /* default: at the end of the session */

    DOMString domain = Location::hostname;
    boolean secure = false;
    boolean sameSite = false;
  }

Then we could finally simply write

  /* Get the number of readable cookies */
  console.log(document.cookies.length);

  /* Get a cookie based on the order in which it was saved */
  console.log(document.cookies[document.cookies.name(1)]);

  /* Retrieve all cookie names an Array */
  console.log(document.cookies.names());

  /* Retrieve all cookie values an Array */
  console.log(document.cookies.values());

  /* Retrieve all cookies as an object */
  console.log(document.cookies.items());

  /* Save/modify session cookie with name “foo” and value “bar=baz” */
  document.cookies['foo'] = 'bar=baz';
  /* equivalent to */
  document.cookies.setItem('bla', 'bar=baz');

  /* Save persistent secure cookie with name “bla” and value “bar=baz” */
  document.cookies['bla'] = {
    value: 'bar=baz',
    expires: Date.tomorrow,  /* “a man can dream, though” */
    secure: true
  };
  /* equivalent to */
  document.cookies.setItem('bla', {
    value: 'bar=baz',
    expires: Date.tomorrow,  /* “a man can dream, though” */
    secure: true
  });

  /* Read the cookie with name “foo”  */
  console.log(document.cookies['foo']);
  /* equivalent to */
  console.log(document.cookies.getItem('foo'));

  /* Delete the cookie with name “foo”  */
  delete document.cookies['foo'];
  /* equivalent to */
  document.cookies.removeItem('foo');

  /* Delete all readable cookies for this URI */
  document.cookies.clear();

instead of all the shebang with constructing and parsing strings.  [In fact, 
it is already possible to use ECMAScript Ed. 6 features to implement this, 
although I would not recommend attempting to modify the document object (as 
it is a host object).]

On the other hand, we have the Web Storage API.³  One major advantage of 
Storage over cookies, in addition to currently easier data handling, is that 
nothing of it is sent in the HTTP request; one major disadvantage of Storage 
over cookies is that the former does not provide for a mechanism to let data 
expire after a specific time: .localStorage stores the data forever (until 
explicitly deleted), and .sessionStorage only for the current session.  As a 
result of the former, storage data can easily fill up the client’s disk 
space with garbage that is never discarded, especially as the length of a 
Storage item can be much longer than a cookie value.

_______
¹ <https://heycam.github.io/webidl/>
² <https://html.spec.whatwg.org/multipage/webstorage.html#the-storage-interface>
³ <https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API>

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#39781

From"Michael Haufe (TNO)" <tno@thenewobjective.com>
Date2021-03-26 15:39 -0700
Message-ID<fce95a29-cdfe-4703-922c-0d296b137310n@googlegroups.com>
In reply to#39780
On Friday, March 26, 2021 at 5:22:39 PM UTC-5, Thomas 'PointedEars' Lahn wrote:

> As I keep thinking about this, one would hope that after all this time that 
> cookies have been around, and given my impression that cookies are not going 
> away anytime soon, a standard DOM attribute and built-in property will 
> finally be introduced to make dealing with cookies easier and less error- 
> prone. 

I've use the following for quite some time. I'd write it a bit differently today but it's been a good enough solution thus far for me:

<https://gist.github.com/mlhaufe/01cc0d183774b3444f89447004fd9607>

[toc] | [prev] | [next] | [standalone]


#39809

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2021-03-31 00:58 +0200
Message-ID<11728310.O9o76ZdvQC@PointedEars.de>
In reply to#39781
Michael Haufe (TNO) wrote:

> On Friday, March 26, 2021 at 5:22:39 PM UTC-5, Thomas 'PointedEars' Lahn
> wrote:
>> As I keep thinking about this, one would hope that after all this time
>> that cookies have been around, and given my impression that cookies are
>> not going away anytime soon, a standard DOM attribute and built-in
>> property will finally be introduced to make dealing with cookies easier
>> and less error- prone.
> 
> I've use the following for quite some time. I'd write it a bit differently
> today but it's been a good enough solution thus far for me:
> 
> <https://gist.github.com/mlhaufe/01cc0d183774b3444f89447004fd9607>

Thank you.  My retrieval/storage code (specifically written backwards 
compatible) looks similar, but I found it a good idea to include the 
possibility of the cookie data not being live so as to make access to
it more efficient.

If you have suggestions for improvement, please let me know:

-- cookie.js ------------------------------------------------------------

/**
 * This library is intended to provide easy access to cookies.
 *
 * Read cookie by name:
 *   cookies['$NAME'] === value
 * Save cookie/update value/properties:
 *   cookies['name'] = value
 *   cookies['name'] = {value: value, properties}
 *   cookies['name'].property = propertyValue  [not yet implemented]
 * Delete cookie (set expires to 0):
 *   delete cookies['name']  (for the current domain)
 *   cookies.removeItem('name', {domain: '$DOMAIN', properties})
 *     (for allowed domains)
 * @type {Object}
 *
 * // begin WebIDL
 *
 * [Exposed=jsx.dom]
 * interface mixin DocumentStorage {
 *   readonly attribute Cookies cookies;
 * }
 *
 * [Exposed=DocumentStorage]
 * interface Cookies {
 *   readonly attribute unsigned long length;
 *   DOMString? name(unsigned long index);
 *   sequence <DOMString> names();
 *   sequence <DOMString> values();
 *   sequence <record <DOMString, CookieAttributes>> items();
 *   getter DOMString? getItem(DOMString name);
 *   boolean hasItem(DOMString name);
 *   setter boolean setItem(DOMString name, DOMString value);
 *   setter boolean setItem(DOMString name, CookieAttributes attributes);
 *   deleter boolean removeItem(DOMString name);
 *   boolean clear();
 * }
 *
 * dictionary CookieAttributes {
 *   required DOMString value;
 *   DOMString path = Location::pathname;
 *   unsigned long? maxAge = null;  // default: end of session
 *
 *   // or unsigned long, but Date would be more convenient
 *   Date? expires = null;  // default: at the end of the session
 *
 *   DOMString domain = Location::hostname;
 *   boolean secure = false;
 *   boolean sameSite = false;
 * }
 *
 * // end WebIDL
 */

/*eslint-env es6 */

jsx.dom.cookies = {
  /** Internal dictionary of cookies */
  _items: Object.create(null),

  /**
   * Determines whether this object uses live data.
   *
   * If <code>true</code>, methods of this object update the internal 
   * dictionary from <code>document.cookie</code>; otherwise they only
   * read from the internal dictionary which can be updated manually
   * by calling {@link #update()}.
   * 
   * Set this property to <code>false</code> to make repeated access
   * more efficient.
   *
   * @type {Boolean}
   */
  live: true,

  Cookie: function (properties) {
    var proto = Object.getPrototypeOf(this);

    Object.keys(properties).forEach(function (key) {
      if (key in proto && (typeof proto[key] != 'function')) {
        var value = properties[key];
        var setterName = 'set' + key.charAt(0).toUpperCase()
          + key.substring(1);

        if (typeof this[setterName] == 'function') {
          this[setterName](value);
        }
        else {
          this[key] = value;
        }
      }
    }.bind(this));
  }.extend(null, {
    name: '',
    value: null,
    path: '',
    maxAge: null,
    expires: null,
    domain: '',
    secure: false,
    sameSite: '',

    setMaxAge: function (value) {
      this.maxAge = parseInt(value, 10);
    },

    setExpires: function (value) {
      this.expires = (value instanceof Date)
        ? value
        : new Date(value);
    },

    setSecure: function (value) {
      this.secure = !!value;
    },

    setSameSite: function (value) {
      if ([void 0, 'lax', 'strict', 'none'].indexof(value) < 0) {
        throw new jsx.InvalidArgumentError(
          'Expected: samesite=(lax | strict | none)');
      }

      this.sameSite = value;
    },

    toString: function () {
      return [this.name, this.value].map(encodeURIComponent).join('=')
        + (this.path ? ';path=' + this.path : '')
        + (this.maxAge ? ';max-age=' + this.maxAge : '')
        + (this.expires ? ';expires=' + this.expires.toUTCString() : '')
        + (this.domain ? ';domain=' + this.domain : '')
        + (this.secure ? ';secure' : '')
        + (this.sameSite ? ';samesite=' + this.sameSite : '');
    }
  }),

  /**
   * Update the internal dictionary from <code>document.cookie</code>.
   *
   * @return {Object} The updated dictionary
   */
  update: function () {
    this._items = Object.create(null);

    var cookies = document.cookie;

    if (cookies.indexOf('=') > 0) {
      cookies.split(/\s*;\s*/)
        .forEach(function (cookie) {
          var parts = cookie.split('=').map(decodeURIComponent);
          var name = parts[0];
          var value = parts.slice(1).join('=');
          this._items[name] = new this.Cookie({name: name, value: value});
        }.bind(this));
    }

    return this._items;
  },

  items: function () {
    if (this.live) this.update();

    return this._items;
  },

  /** @return int */
  length: function () {
    return this.names().length;
  },

  /** @return String */
  name: function (/** int */ index) {
    return this.names()[index];
  },

  /** @return Array[String] */
  names: function () {
    return Object.keys(this.items());
  },

  /** @return sequence <DOMString> */
  values: function () {
    return this.names().map(function (name) {
      return this.getItem(name).value;
    }.bind(this));
  },

  /** @return getter DOMString? */
  getItem: function (/** DOMString */ name) {
    return this.items()[name];
  },

  /** @return boolean */
  hasItem: function (/** DOMString */ name) {
    return (name in this.items());
  },

  /** @type setter boolean */
  setItem: function (/** DOMString */ name, /** DOMString */ value) {
    var cookie;

    if (jsx.object.isObject(value)) {
      cookie = new this.Cookie(value);
    }
    else {
      cookie = new this.Cookie({name: name, value: value});
    }

    this._items[name] = cookie;
    document.cookie = cookie.toString();
  },

  /**
   * Delete a cookie
   *
   * @deleter
   * @param  {DOMString} name
   * @return {[type]}
   *   <code>true</code> if successful, <code>false</code> otherwise.
   */
  removeItem: function (name) {
    document.cookie = (new this.Cookie({
      name: name,
      expires: 0
    })).toString();

    this.update();
    return !this.hasItem(name);
  },

  /** @return boolean */
  clear: function () {
    this.names().forEach(function (name) {
      this.removeItem(name);
    }.bind(this));
  }
};

if (typeof Proxy == 'function')
{
  jsx.dom.cookies = new Proxy(jsx.dom.cookies, {
    get: function (target, propertyName) {
      if (propertyName in target)
      {
        return target[propertyName];
      }

      return target.getItem(propertyName);
    },
    set: function (target, propertyName, value) {
      if (propertyName in target)
      {
        target[propertyName] = value;
      }
      else {
        target.setItem(propertyName, value);
      }
    },
    deleteProperty: function (target, propertyName) {
      if (!(propertyName in target))
      {
        return target.removeItem(propertyName);
      }
    }
  });
}
-------------------------------------------------------------------------

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#39810

From"Michael Haufe (TNO)" <tno@thenewobjective.com>
Date2021-03-30 19:58 -0700
Message-ID<d68097e8-2a6c-4cdc-86cc-9fd3cb2ab1bdn@googlegroups.com>
In reply to#39809
On Tuesday, March 30, 2021 at 5:58:09 PM UTC-5, Thomas 'PointedEars' Lahn wrote:
> Thank you. My retrieval/storage code (specifically written backwards 
> compatible) looks similar, but I found it a good idea to include the 
> possibility of the cookie data not being live so as to make access to 
> it more efficient. 
> 
> If you have suggestions for improvement, please let me know: 
>
> [...]
>
> jsx.dom.cookies = { 
> [...] 
> } 

Modernization to modules and other ECMAScript features is my primary suggestion.

After seeing your local cache I wonder if it's worth extending the Map class instead:

class Cookies extends Map {
    ...
}

You would then get the iteration methods and more functionality for free. 

[toc] | [prev] | [next] | [standalone]


#39817

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2021-04-01 10:09 +0200
Message-ID<5455208.DvuYhMxLoT@PointedEars.de>
In reply to#39810
Michael Haufe (TNO) wrote:

> On Tuesday, March 30, 2021 at 5:58:09 PM UTC-5, Thomas 'PointedEars' Lahn
> wrote:
>> Thank you. My retrieval/storage code (specifically written backwards
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> compatible) looks similar, but I found it a good idea to include the
   ^^^^^^^^^^
>> possibility of the cookie data not being live so as to make access to
>> it more efficient.
>> 
>> If you have suggestions for improvement, please let me know:
>>
>> [...]
>>
>> jsx.dom.cookies = {
>> [...]
>> }
> 
> Modernization to modules and other ECMAScript features is my primary
> suggestion.

<facepalm/>  See above. 

> After seeing your local cache I wonder if it's worth extending the Map
> class instead:
> 
> class Cookies extends Map {
>     ...
> }
> 
> You would then get the iteration methods and more functionality for free.

Thank you, I will consider it.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#39819

From"Michael Haufe (TNO)" <tno@thenewobjective.com>
Date2021-04-01 06:11 -0700
Message-ID<8445649b-5b5f-43c8-85d4-7919ac8553e0n@googlegroups.com>
In reply to#39817
On Thursday, April 1, 2021 at 3:09:30 AM UTC-5, Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote: 
> 
> > On Tuesday, March 30, 2021 at 5:58:09 PM UTC-5, Thomas 'PointedEars' Lahn 
> > wrote: 
> >> Thank you. My retrieval/storage code (specifically written backwards
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >> compatible) looks similar, but I found it a good idea to include the
> ^^^^^^^^^^
> > Modernization to modules and other ECMAScript features is my primary 
> > suggestion.
> <facepalm/> See above.

Yes, I saw it but why is that necessary anymore with compilation? This is simply a flag now in babel.

[toc] | [prev] | [next] | [standalone]


#39833

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2021-04-01 19:34 +0200
Message-ID<4643966.31r3eYUQgx@PointedEars.de>
In reply to#39819
Michael Haufe (TNO) wrote:

> On Thursday, April 1, 2021 at 3:09:30 AM UTC-5, Thomas 'PointedEars' Lahn
> wrote:
>> Michael Haufe (TNO) wrote:
>> > On Tuesday, March 30, 2021 at 5:58:09 PM UTC-5, Thomas 'PointedEars'
>> > Lahn wrote:
>> >> Thank you. My retrieval/storage code (specifically written backwards
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> >> compatible) looks similar, but I found it a good idea to include the
>> ^^^^^^^^^^
>> > Modernization to modules and other ECMAScript features is my primary
>> > suggestion.
>> <facepalm/> See above.
> 
> Yes, I saw it but why is that necessary anymore with compilation? This is
> simply a flag now in babel.

Not everybody uses Babel.  I for one do not (yet?).

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#39777

FromThe Natural Philosopher <tnp@invalid.invalid>
Date2021-03-26 17:10 +0000
Message-ID<s3l4iv$t8n$1@dont-email.me>
In reply to#39768
On 26/03/2021 16:31, Thomas 'PointedEars' Lahn wrote:
> Daniele wrote:
> ^^^^^^^
> Please post using your real name (first name and last name suffice).
Please refrain from silly monikers like 'pointed ears'

[toc] | [prev] | [next] | [standalone]


#39786

FromDaniele <webmaster@appliserver.com>
Date2021-03-27 12:16 +0100
Message-ID<s3n477$aje$1@dont-email.me>
In reply to#39777
Il 26/03/2021 18:10, The Natural Philosopher ha scritto:
> On 26/03/2021 16:31, Thomas 'PointedEars' Lahn wrote:
>> Daniele wrote:
>> ^^^^^^^
>> Please post using your real name (first name and last name suffice).
> Please refrain from silly monikers like 'pointed ears'

No, I know PE (its digital personality at least) from long time.
He is a bit nitpicking and pedantic, but if you take from him "the good 
parts" (cit.) he is a valuable contributor.

So my advice is to listen at him, maybe avoiding accurately to debate 
with him about his "recommendations"...

Dan

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.javascript


csiph-web