The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly. |
![]() |
Home ![]() ![]() ![]() ![]() |
|
![]() ![]() ![]() ![]() ![]() ![]() |
|
Server-Side Workarounds: Content Negotiation
Apache variants filesAddHandler type-map var The server must be restarted for this line to take effect. Then, for each
image that is to be negotiated, create a .var file corresponding
to the filename and refer to that in the HTML file. For example, to serve
either tux.gif or tux.png, depending on each browser's
capabilities, create a file called tux.var in the same directory
and refer to it in the IMG tag in place of the actual image filename:
<IMG SRC="images/tux.var" ALT="[His Penguinness, Tux]"> The contents of tux.var should look something like this: URI: tux.png Content-Type: image/png;qs=0.7 URI: tux.gif Content-Type: image/gif;qs=0.4 Each variant has a corresponding block of information, separated from that of the other variants by blank lines. The actual image filenames are given on the URI lines, and their corresponding MIME types are given on the subsequent Content-Type lines. In addition, a quality of source parameter qs is included for each image type. This is a number between 0.0 and 1.0 that indicates the relative preferences of the author for each image type. In this example, I've indicated that the PNG image (0.7) is preferred over the GIF (0.4). The default value of the qs parameter is 1.0. A client browser requesting an image from the server also indicates its relative preferences, either explicitly or implicitly, via the HTTP Accept header. The web server then multiplies its quality parameter for each MIME type by the client's quality parameter[19] to get a composite value--this is the resolution phase of the negotiation. The highest composite value determines which image is sent.
In practice, things are a bit more complicated for the server, but this is usually hidden from the user. The problem arises when the client browser sends incomplete or even incorrect information. For example, some browsers send Accept: image/* , indicating that they can render any type of image. Others specify a list of image types but also include the catchall type */*. And only rarely does a client include preference values for each type. As a result, the server must assume preference values for the client. By default, all types are given a value of 1.0, but Apache ``fiddles'' the values for wildcard types: image/* or text/* are assigned the value 0.02 instead, and */* is assigned the value 0.01. The variants file approach allows fine-grained control over every image in a web site, and has the distinct advantage that a site designer can use it at will, if the server administrator has enabled content negotiation. But maintaining parallel sets of images can be enough trouble all by itself; having to maintain a unique variants file for every image is enough to drive most site maintainers to distraction. Fortunately, Apache provides a partial alternative: MultiViews, a directory-wide (and potentially server-wide) method based on file extensions. Apache MultiViewsOptions +MultiViews The option may appear inside a <Directory> container, in which case it applies only to the named directory tree rather than the entire server; inside a <VirtualHost> container, in which case it applies only to a given virtual hostname; or, if AllowOverride Options has been specified, within .htaccess files in individual directories. As with variants, the server must be restarted before changes to the main configuration file are noticed. Once MultiViews is enabled for a given directory--say, /www/htdocs/images--a request for a file foo in that directory will either return foo if it exists or else negotiate between all foo.* files. So to serve either tux.png or tux.gif, for example, simply include both in the directory and refer to them as follows: <IMG SRC="images/tux" ALT="[His Penguinness, Tux]"> Unfortunately, MultiViews has one great weakness: no version of Apache
through 1.3.3 supports multifile quality-of-source settings.[20]
|
|
Home ![]() ![]() ![]() ![]() |