Re: CGI::cookie query
by suaveant (Parson) on Apr 02, 2001 at 19:25 UTC
|
Something you may want to think about... there is a limit to
something like 20 cookies per site in browsers, after that
they delete them. Each cookie can be like, 1 or 4k not sure which,
you may just want to encode your hash into a single string
and write it into a single cookie.
something like: $cookie = join "\0", %hash;
$cookie =~ s/(\W)/'%'.sprintf("%02lx",ord($1))/ge;
#... print cookie ...
#read cookie back to hash...
$cookie =~ s/%([a-fA-F\d][a-fA-F\d])/chr(hex($1))/ge;
%hash = split "\0", $cookie;
as long as you don't have a really large hash, or one that contains \0 in it,
that oughtta work fine and solve your problem
- Ant | [reply] [d/l] |
Re: CGI::cookie query
by wardk (Deacon) on Apr 02, 2001 at 20:12 UTC
|
Within a CGI script you can send a cookie to the browser by creating
one or more Set-Cookie: fields in the HTTP header. Here is a typical
sequence:
my $c = new CGI::Cookie(-name => 'foo',
-value => ['bar','baz'],
-expires => '+3M');
print "Set-Cookie: $c\n";
print "Content-Type: text/html\n\n";
To send more than one cookie, create several Set-Cookie: fields.
Alternatively, you may concatenate the cookies together with "; " and
send them in one field.
Just do the Set-Cookie in your loop and the header after...
| [reply] [d/l] |
|
|
The problem is is that the cookie values must not be concatenated, they have to be sent as seperate cookies (project rules).
..I also have to use the CGI::cookie module (hence no use of set-cookie)
| [reply] |
Re: CGI::cookie query
by Masem (Monsignor) on Apr 02, 2001 at 20:37 UTC
|
Another way that isn't mentioned already: You can only send the CGI header *once*, so that call to header() will be weird. But all you need to do is create an array of cookies and then call header once after the loop; eg replace that last line of the loop with push @cookies, $cookie;, then call print $query->header(-cookie=>@cookies); (note: untested, may have to use a reference to @cookies).
But as other have send, there's a practical limit to cookies. It's better to only send one piece of data across and use a server at your end to extract all the data that you are trying to send now. So you'd create a unique key, write to some database all the info you're trying to save, then send off the cookie with just that key value. Upon getting back that key value by a cookie, it's a lot easier to get that data.
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] [d/l] [select] |
|
|
THis seems like the best idea!!!
I have tried it however with no success. What did you actually mean by
'may have to use a reference to @cookies'
Does anybody know if it is possible to writea cookie with an array
$query->header(-cookie=>@cookies);
| [reply] |
|
|
Use $query->header( -cookie=> \@cookies ); (note the '\', that makes the call use a reference to @cookies as opposed to the variable @cookies itself), instead of what I had initially. Again, it's untested, so it might not work, though I doubt that it won't work this way.
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] [d/l] |
|
|
|
|
Re: CGI::cookie query
by wardk (Deacon) on Apr 02, 2001 at 21:44 UTC
|
#!/bin/perl
use CGI qw/:standard/;
use CGI::Cookie;
use strict;
my @cookie;
# do this in a loop....
$cookie[0] = new CGI::Cookie(-name=>'ID',-value=>123456);
$cookie[1] = new CGI::Cookie(-name=>'preferences',
-value=>{ font => 'Helvetica', size => '12' });
print header(-cookie=>\@cookie);
which produces....
Set-Cookie: ID=123456
Set-Cookie: preferences=size&12&font&Helvetica
Date: Mon, 02 Apr 2001 17:42:01 GMT
Content-Type: text/html
| [reply] [d/l] [select] |
|
|
Ive tried your script aswell. This is what im doing but it just wont put them all in the cookie.
$inputs is a hash which contains only 9 instances (not over 4k).
sub set_cookie_value
{
my ($inputs) = @_;
my @cookies = ();
my $key;
foreach $key (keys %$inputs)
{
$cookie = new CGI::Cookie(-name=>$key, -value=>$inputs->{$key}
+, -expires=>$inputs->{$key}, -path=>'/', -domain=>'', -secure=>0);
push (@cookies, $cookie);
}
print header( -cookie=>\@cookies );
print "--$inputs->{'postcode'}--"
}
Any further ideas? | [reply] [d/l] |
|
|
what is the programs output?
you can determine this by running it from a command line,
CGI.pm will prompt you for some input variables (you can also pass
them on the command line), like so: (line 1 is executing the script,
2 is the script prompting me for input, 3 is my input. between lines
3 and 4 I hit Ctrl-D, lines 4-7 is the output. in this case 2 cookies.
1 xdev$ perl cook.pl
2 (offline mode: enter name=value pairs on standard input)
3 foo=bar
4 Set-Cookie: ID=123456
5 Set-Cookie: preferences=size&12&font&Helvetica
6 Date: Tue, 03 Apr 2001 21:01:04 GMT
7 Content-Type: text/html
xdev$
note the code executed above is the same code posted
in the previous node | [reply] [d/l] |
Re: CGI::cookie query
by suaveant (Parson) on Apr 02, 2001 at 19:38 UTC
|
I also just realized... now, I don't really use CGI.pm,
but it seems to me writing the cookie with the same name
over and over again could be overwriting your old one in
CGI::Cookie? I may be wrong.
- Ant | [reply] |