📄 ch13.htm
字号:
add them to a list of new users.<BR>
if (grep(!/$user2/,@users))
{ push(@newusers,$user2); }<BR>
}<BR>
foreach $user (@users) {<BR>
# If any of the
users last time through are not<BR>
# present this
time, add them to a list of old<BR>
# users.<BR>
if (grep(!/$user/,@users2))
{ push(@oldusers,$user); }<BR>
}<BR>
# If no one has logged in or out since
last time, don't do<BR>
# anything. This way a new HTML page is
only sent when a<BR>
# change is made.<BR>
if (@newusers || @oldusers) {<BR>
$who = join("<br>\n",@who);
# Translate linefeeds to <BR>s.<BR>
<BR>
# Print the boundary,
headers, and beginning of message.<BR>
print <<EOX;
<BR>
--I_Like_Snow<BR>
Content-type: text/html<BR>
<BR>
<HTML><HEAD><TITLE>Current Users</title></head><BODY>
<BR>
Current Users:<br><BR>
$who<BR>
<br><BR>
EOX<BR>
# List everyone
who has logged on since last time.<BR>
foreach (@newusers)
{<BR>
print
"$_ has logged on!<br>\n";<BR>
}<BR>
# List everyone
who has logged out since last time.<BR>
foreach (@oldusers)
{<BR>
print
"$_ has logged off!<br>\n";<BR>
}<BR>
print "</body></html>\n";
<BR>
}<BR>
# Wait 10 seconds then do it again.<BR>
sleep 10;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
This script is just a sample of what you can do with server push.
Even though it has lost the spotlight to newer and flashier technologies,
server push can still yield great results when applied creatively.
<H2><A NAME="HTTpcookies"><FONT SIZE=5 COLOR=#FF0000>HTTP Cookies</FONT></A>
</H2>
<P>
Aside from being great with milk, cookies have become one of the
most discussed server extensions ever. HTTP cookies are an attempt
to solve one of the great hurdles of working with CGI: state retention.
<P>
Transfer over the Web is transient. Once the server sends the
document to the client, it forgets that the client ever existed.
If a user browses through a hundred pages on the same site, they
make a hundred separate connections to the same server.
<P>
This presents a big problem for CGI programs. Almost all CGI-based
applications, from games to databases, need to store information
about the person using them between calls to the program. Traditionally,
this requires saving information in temporary files or hidden
variables in HTML forms. For instance, a series of CGI programs
that interact with a database might ask for a username on the
first page, save the data to a temporary file, and then pass the
username and temporary filename from CGI to CGI by using hidden
variables.
<P>
If this all sounds complicated, that's because it is. Cookies
are an attempt to simplify this by allowing the browser to store
information sent to it by the server. The browser then sends the
information back each time it accesses that server. To avoid filling
up the hard drive of the end user, cookies are generally very
short pieces of information: usually an ID number or filename
of a file on the server that contains more information.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Although called server extensions, almost everything discussed in this chapter must also have support on the client side. This is especially true for HTTP cookies. Unless the browser has the capability to store the cookie information, your CGI can't do
anything with it. At the time of this writing, several major browsers still have not implemented HTTP cookies, including Lynx-FM and ncSA Mosaic. If your pages absolutely depend on cookies, it's a good idea to provide an alternate mechanism for people who
have no access to a cookie-capable browser.</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
Like server push, HTTP cookies are implemented through the HTTP
header that is sent <BR>
before the document itself. The value of a cookie is passed to
the client through the header <TT><FONT FACE="Courier">Set-Cookie</FONT></TT>.
The full syntax, as it would appear to a browser receiving a cookie,
is as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Set-Cookie: name=value; expires=date;
path=path; domain=domain; secure</FONT></TT>
</BLOCKQUOTE>
<P>
Everything except for <TT><FONT FACE="Courier">name=value</FONT></TT>
is optional. The following list outlines each part in more detail:
<UL>
<LI><TT><FONT FACE="Courier">name=value</FONT></TT>-This is the
actual cookie. <TT><FONT FACE="Courier">name</FONT></TT> and <TT><FONT FACE="Courier">value</FONT></TT>
can be anything as long as they don't contain semicolons, commas,
or white space. (You can use URL-encoded equivalents in their
place.)
<LI><TT><FONT FACE="Courier">expires=date</FONT></TT>-<TT><FONT FACE="Courier">date</FONT></TT>
must be formatted as follows:<BR>
<TT><FONT FACE="Courier">Wdy, DD-Mon-YYYY HH:MM:SS GMT</FONT></TT>.
If the browser supports it, the cookie is deleted after the <TT><FONT FACE="Courier">expires</FONT></TT>
date has been reached.
<LI><TT><FONT FACE="Courier">path=path</FONT></TT>-<TT><FONT FACE="Courier">path</FONT></TT>
(on the right-hand side) is the uppermost directory for which
the cookie is valid. If <TT><FONT FACE="Courier">path</FONT></TT>
is a file, the cookie is only valid for that file. <TT><FONT FACE="Courier">path</FONT></TT>
is the URL path, not the path on the server file system. (For
example, the path for <TT><FONT FACE="Courier">http://foo.bar.com/my/dir/</FONT></TT>
is <TT><FONT FACE="Courier">/my/dir</FONT></TT>.) The path <TT><FONT FACE="Courier">/</FONT></TT>
encompasses all URLs within the server machine.
<LI><TT><FONT FACE="Courier">domain=domain</FONT></TT>-<TT><FONT FACE="Courier">domain</FONT></TT>
(on the right-hand side) is the subset of all Internet domains
for which the cookie is valid. For example, a domain of <TT><FONT FACE="Courier">.msu.edu</FONT></TT>
creates a cookie that is activated for all hosts that end in <TT><FONT FACE="Courier">msu.edu</FONT></TT>.
The domain must have at least two dots to prevent someone from
giving out cookies that activate for any domain.
<LI><TT><FONT FACE="Courier">secure</FONT></TT>-If the <TT><FONT FACE="Courier">secure</FONT></TT>
flag is present, the cookie is only transmitted through HTTPS
servers. This only has meaning to servers that support the SSL
protocol, which are very few (mainly the Netscape Secure Server).
</UL>
<P>
Every time a URL is entered into a cookie-aware browser, the browser
checks to see if it has any cookies that belong to the domain
of the URL. If it finds any, it checks them to see if the URL's
path contains the path of any of the cookies. If any do, it sends
the following as a header back to the server:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Cookie: name=value</FONT></TT>
</BLOCKQUOTE>
<P>
If more than one cookie matches, the client returns
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Cookie: name1=value1; name2=value2</FONT></TT>
</BLOCKQUOTE>
<P>
for as many cookies as are valid.
<P>
If two or more cookies have the same name (which is possible if
they have different paths), the browser sends them all. If the
server is cookie-aware, it sets the environment variable <TT><FONT FACE="Courier">HTTP_COOKIE</FONT></TT>
once it receives the cookie header. It is through this environment
variable that CGI programs retrieve the cookie information.
<P>
Listing 13.2 is a simple Perl script that displays any cookies
that are sent from the browser.
<HR>
<BLOCKQUOTE>
<B>Listing 13.2. Display cookies sent from the browser.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!/usr/local/bin/perl -Tw<BR>
<BR>
print <<EOP; # Print headers and beginning of message.<BR>
Content-type: text/html<BR>
<BR>
<HTML><HEAD><TITLE>Mmmmm.... Cookies</title></head><BODY>
<BR>
EOP<BR>
<BR>
if (!$ENV{'HTTP_COOKIE'}) {<BR>
# The server puts cookie information into
the environment<BR>
# variable 'HTTP_COOKIE. If there are
no cookies, print a<BR>
# message then leave.<BR>
<BR>
print <<EOP;<BR>
Sorry, the browser didn't send you any cookies!<BR>
</body></html><BR>
EOP<BR>
die;<BR>
}<BR>
<BR>
print "<H1>Your Cookies</h1>\n";<BR>
<BR>
$cookies = $ENV{'HTTP_COOKIE'};<BR>
<BR>
# Split the cookie string up into individual cookies.<BR>
@cookies = split(/; */, $cookies);<BR>
<BR>
foreach (@cookies) {<BR>
# For each of the cookies, split the cookie
up into two parts:<BR>
# The name (key) and the value.<BR>
( $key, $val ) = split(/=/, $_);<BR>
<BR>
# If more than one cookie has the same
name, combine their<BR>
# values, separated by commas. (The syntax
of the HTTP header<BR>
# already guarantees that there are no
commas in the cookie.)<BR>
if ($COOKIE{$key}) { $COOKIE{$key} .=
",$val"; }<BR>
else { $COOKIE{$key} = $val; }<BR>
}<BR>
<BR>
# Now go through each of the cookies in alphabetical order.<BR>
foreach (sort keys %COOKIE) {<BR>
<BR>
# If the cookie's value has a comma in
it, it must be a multiple<BR>
# cookie.<BR>
if ($COOKIE{$_} =~ /,/) {<BR>
# Split the multiple
cookie up in to each value...<BR>
@vals = split(/,/,$COOKIE{$_});
<BR>
foreach $valu
(@vals) {<BR>
#
...and print each value as a separate cookie.<BR>
print
"$_ => $valu<br>\n";<BR>
}<BR>
} else {<BR>
print "$_
=> $COOKIE{$_}<br>\n";<BR>
}<BR>
}<BR>
# Say bye bye.<BR>
print "</body></html>\n";</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
You could easily turn the core code of the preceding script into
a subroutine that returns the hash <TT><FONT FACE="Courier">%COOKIE</FONT></TT>
containing all the cookie values. It is useful to do this if you
use cookies often. Including this subroutine in an external package
allows you to check for cookies easily in any CGI script.
<P>
Now that you can store and retrieve cookies, what good are they?
Originally, they were mainly used for storing user preferences
and to facilitate "shopping cart" systems. The ability
to store data on the client side has proven to be very versatile.
If you have access to a Netscape browser (version 2.0 or greater),
turn on the option that brings up a requester every time you are
presented with a cookie. It is amazing to see the number of sites
using cookies for one reason or another.
<P>
To some people, it is also frightening. Of the two main reasons
for using cookies, storing user preferences has come under great
scrutiny as a possible danger to privacy. Soon after cookies were
developed, many sites advertised the capability to alter their
pages to suit a user's preference, which is done using cookies.
Every page a user visits on one of these sites sends the browser
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -