Implementation Notes - Server-Side Scripting
June 21, 1999
Because the emphasis in server-side scripting is on dynamic
content, it doesn't make for very cacheable pages, even when the
content could be cached. If your content changes often, but not on
every page hit, consider setting an Expires header, even if just
for a few hours. Most users access pages again in a relatively
short period of time. For instance, when users hit the 'back'
button, if there isn't any validator or freshness information
available, they'll have to wait until the page is re-downloaded
from the server to see it.
-
One thing to keep in mind is that it may be easier to set HTTP
headers with your Web server rather than in the scripting
language. Try both.
CGI
CGI scripts are one of the most popular ways to generate content.
You can easily append HTTP response headers by adding them before you send the
body; Most CGI implementations already require you to do this for the Content-Type
header. For instance, in Perl;
#!/usr/bin/perl
print "Content-type: text/html\n";
print "Expires: Thu, 29 Oct 1998 17:04:19 GMT\n";
print "\n";
### the content body follows...
Since it's all text, you can easily generate Expires and other
date-related headers with in-built functions. It's even easier if you use
Cache-Control: max-age;
print "Cache-Control: max-age=600\n";
This will make the script cacheable for 10 minutes after the request, so
that if the user hits the 'back' button, they won't be resubmitting the
request.
The CGI specification also makes request headers that the client sends available
in the environment of the script; each header has 'HTTP_' appended to its name.
So, if a client makes an If-Modified-Since request, it may show up like this:
HTTP_IF_MODIFIED_SINCE = Fri, 30 Oct 1998 14:19:41 GMT
Server Side Includes
SSI (often used with the extension .shtml) is one of the first
ways that Web publishers were able to get dynamic content into
pages. By using special tags in the pages, a limited form of
in-HTML scripting was available.
Most implementations of SSL do not set validators, and as such
are not cacheable. However, Apache's implementation does allow
users to specify which SSI files can be cached, by setting the
group execute permissions on the appropriate files, combined with
the XbitHack full directive. For more information, see
http://www.apache.org/docs/mod/mod_include.html
PHP 3
PHP (http://www.php.net/) is a
server-side scripting language that, when built into the server,
can be used to embed scripts inside a page's HTML, much like SSI,
but with a far larger number of options. PHP can be used as a CGI
script on any Web server (Unix or Windows), or as an Apache
module.
By default, objects processed by PHP are not assigned
validators, and are therefore uncacheable. However, developers can
set HTTP headers by using the Header() function.
For example,
this will create a Cache-Control header, as well as
an Expires header three days in the future:
$ExpireString = "Expires: " . \
gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
Remember that the Header() function MUST come before any other
output.
As you can see, you'll have to create the HTTP date for an
Expires header by hand; PHP doesn't provide a function to do it for
you. Of course, it's easy to set a Cache-Control: max-age header, which
is just as good for most situations.
For more information, see
http://www.php.net/manual/function.header.php3
Cold Fusion 4.0
Cold Fusion, by Allaire (http://www.allaire.com/) is a
commercial server-side scripting engine, with support for several
Web servers on Windows and Solaris.
Cold Fusion makes setting arbitrary HTTP headers relatively
easy, with the CFHEADER tag. Unfortunately, setting date-related
functions in Cold Fusion isn't easy as Allaire's documentation
leads you to believe; their example for setting an Expires header,
as below, won't work.
<CFHEADER NAME="Expires" VALUE="#Now()#">
It doesn't work because the time (in this case, when the request
is made) doesn't get converted to a HTTP-valid date; instead, it
just gets printed as a representation of Cold Fusion's Date/Time
object. Most clients will either ignore such a value, or convert it
to a default, like January 1, 1970.
Cold Fusion's date formatting functions make it difficult generate
a date that is HTTP-valid; you'll need to either use a combination of
DateFormat, Hour, Minute and Second,
or roll your own. Of course, you can still use the CFHEADER tag
to set Cache-Control: max-age and other headers.
Also, Remember that Web server headers are passed through with some
implementations (such as CGI); check yours to determine whether you
can use this to your advantage, by setting headers on the server
instead of in Cold Fusion.
ASP
Active Server Pages, build into IIS and now becoming available
in other implementations, also allow you to set HTTP headers. For
instance, to set an expiry time, use the properties of the Response
object in your page, like this:
<% Response.Expires=1440 %>
specifying the number of minutes from the request to expire the
object. Likewise, absolute expiry time can be set like this (make
sure you format HTTP date correctly):
<% Response.ExpiresAbsolute=#May 31,1996 13:30:15 GMT# %>
Cache-Control headers can be added like this:
<% Response.CacheControl="public" %>
- When setting HTTP headers from ASPs, make sure you either place
the Response method calls before any HTML generation, or use
Response.Buffer to buffer the output.
- Note that ASPs set a Cache-Control: private header by default,
and must be declared public to be cacheable by HTTP 1.1 shared
caches. While you're at it, consider giving them an Expires header
as well.
A Note About the HTTP
Caching Tutorial for Web Authors and Webmasters
References and Further Information
|