A more detailed look
Data encoding for CGI

Whether the browser client copies it from an HTML tag or constructs it from a filled-in HTML form, user data sent to a CGI takes the form of scalar parameter assignments — item=textstring — joined by & signs. If the complete data set is fairly short, it can be spliced onto the base URL with a ? mark, in this manner

 http://www.yoursite.com/some.cgi?user=maxhax&frames=no
and sent as an HTTP GET request. Alternatively, user data may (or must, if it’s lengthy) be sent detached from the URL — but wrapped with the URL — in an HTTP POST request. The remote server knows, based on detecting either GET or POST, where to find the form data.

If the user data contains characters such as spaces or / : & that could confuse the meaning of the composite URL, those characters are replaced by “escaped” representations consisting of % followed by the two-digit hexadecimal value of the offending character (spaces, forbidden in URLs, may be rendered as + signs or escaped as %20 — of course, real plus signs are first escaped as %2B , and real % signs as %25 ). After the request arrives safely at the remote server, the CGI routine accepting the data reconverts the escaped characters.

From the browser’s viewpoint

The request originates from a hard-coded HTML tag (Anchor, IMaGe, SCRIPT, and so on); or it’s constructed [in conformance with CGI standards] from data currently available in a form, at the moment when a Submit button (or image with equivalent function) is clicked. The browser treats <IMG SRC="hooters.jpg"> and †<IMG SRC="getimage.cgi?id=0069">† exactly the same — it’s the CGI process at the server that must determine from the user data, in the latter case, just what it is expected to do.

A standard HTML page (or an image, or a javascript, or whatever the CGI is supposed to deliver) comes back from the server and is handled in the usual way. The browser really can’t tell, and doesn’t care, whether the response came from a static file or was built “on the fly.”

At the distant Web server

The server recognizes the requested resource’s name [perhaps ending in .cgi or .pl] or path (directory) as being reserved on that particular server for CGI. Therefore, it fills the request by running the named script/module and returning the resulting output — rather than simply sending out the URL-specified file, as would occur with non-CGI requests.

The user data (string of parameter/value pairs) is extracted from the appropriate part of the request packet and left in a designated location shared by the server and CGI processes. The named CGI routine is signaled to begin executing.

The CGI routine “un-escapes” any character encoding of the data and creates or retrieves whatever type of object it was asked to. Often it’s still another process (such as a database engine or a graphics drawing utility) that does the “heavy lifting” of supplying the actual core content — the CGI “gateway” has to comply with data and parameter formats used by these additional processes, while delivering its own output as a file of a type the requesting [remote] client recognizes (nearly always HTML, plain text, javascript text, or image). The CGI routine usually is also responsible for supplying HTTP headers describing the data by MIME type.

Based on a signal from the CGI routine, the server may attach various standard HTTP headers [and presumably status code 200 OK] ahead of the CGI’s generated byte stream. The server then ships out the result in the same way it would a static file.

What about PHP and ASP?

PHP achieves the same goal as CGI — customized Web content in response to user input — in a more clever and efficient way.

PHP commands are embedded inside a Web page’s source file, bracketed like HTML comments. The PHP interpreter [which is part of the Web server] strips the commands out when the page is requested and replaces them with whatever content they call for. (PHP has access to query strings, browser signatures, etc. just as CGI modules do.)

Since there is no need to re-launch a CGI process for every page fetched, things run much faster. And PHP is open-source, so it’s rock solid and available for all leading server platforms.

ASP is a lame Micros—t attempt to do what PHP was already doing better. In the grand M$ tradition, ASP is slow, non-portable and full of gratuitous ‘features’ that lead to unexpected behaviors and security flaws. Don’t go there.