Attaching Files to Forms
Here's a relatively easy question for anyone who has been working with the Web for a while: How would you allow visitors to your site to send you their name and address? The easiest solution would be to use an HTML form containing one or more text fields. The contents of the form would be sent to a CGI program on the site's server, which would retrieve the fields' contents.
What if we were interested in sending more than just a few words or phrases? What if we were interested in allowing visitors to our site to enter large volumes of text? We could use a <textarea> tag, which gives the user much more room in which to write. But <textarea> elements, like all HTML form elements, are still a bit clunky. Wouldn't it be nice if there were a way to simply attach a file to an HTML form, much as we can attach files to e-mail messages?
Using the relatively unknown file element, we can do just that. File elements are in many ways similar to text and hidden elements, in that they contain strings of text, rather than simple on-off indicators (as with check boxes) or one of a number of possible strings (as with radio buttons and selection lists). In addition to sending the name of the file, file elements send the contents of the file along with the HTML form.
Before we get to some practical uses for the file element, let's look at a simple example of what is possible. Our initial form shown in Listing 1 contains a single file element and a submit button. It is similar to forms that we have seen in previous installments of At the Forge and is probably quite similar to forms that you have seen on other web sites. The form begins with a <form> tag indicating the method that should be used when sending the data (POST) and the CGI program to which the data is to be sent (/cgi-bin/upload-file.pl). We then have a single form element, as well as a “submit” button for sending the data.
There are two differences between this form and the forms that we have seen before. For starters, the form element has a third attribute (ENCTYPE) that we can generally ignore, because the default value (application/x-www-form-urlencoded) is sufficient for most purposes. However, URL-encoding (in which characters are replaced by a percent sign followed by their ASCII code in hexadecimal, e.g., the space character becomes %20) is inefficient when used on large files, particularly when those files contain a large number of characters that require the coding. In addition, we want to separate the form elements from the file (or files) being uploaded, and we want to tag the uploaded file with a MIME-style content-type header indicating the type of data that is being sent.
For all of these reasons, using the form element requires the use of a new ENCTYPE setting (one defined in RFC 1867 available on the Web at http://www.internic.net/): multipart/form-data. With this encoding type, the contents of each uploaded file will be sent separately, without URL-encoding and with a “Content-type” header describing the type of data contained within. Aside from having to remember to set the encoding type explicitly at the top of any forms containing file elements, we do not have to worry too much about the way in which files are submitted to our CGI programs.
The other new element in the above form is the file element itself. When presented in HTML source code, a file element appears to be quite similar to a “text” element. We assign it a name, and the value will presumably come from the user.
The file element is different from other elements in two ways. First of all, it tells the user's browser to send not just the file name specified in the file element, but also the contents of the file associated with that name.
More obvious to the user, however, is the fact that a file element appears in the user's browser as the combination of a text field and a button. The user can enter a filename by typing into the text field, or—and this is the unusual part—she can browse through the file system using a dialog box brought up by the “browse” button. When the user selects a file to upload by using the “browse” button, the name of the file is entered into the text field, as if the user had typed it.
Now that we know how to set up the form for uploading files, let's look at a small CGI program that will accept the file that was uploaded. For starters in Listing 2 we will simply have our program print the uploaded file on the screen.
Let's run through this program, in case you aren't completely familiar with CGI programs written in Perl. First of all, we start up Perl with the -w flag to warn us if we are doing something particularly stupid. We also turn on diagnostics so that Perl will give us a verbose error message if and when it detects an error.
Normally, any program I write includes the line use strict to catch potentially dangerous or foolish constructs that I might have built. However, as you will see, we will be playing some games with references later on, and we must turn off the strict package when dealing with references so that our program does not crash. Immediately after importing the “strict” module, we thus turn off strict checking on references by using the “no” pragma (a construct for telling Perl how to handle your program).
Then, we load CGI.pm, the package that takes care of most of the dirty work for CGI programs. We create an instance of CGI and use the “header” method to send an initial MIME-style header to the user's browser, indicating that we will be sending HTML-encoded text in our response.
Next, we retrieve the value of the file name entered by the user from the form element named userfile and put it into a variable named $userfile. Until now, $userfile could have come from a text or hidden element as easily as from a form element.
Now comes the wild part. We use $username as a file handle, and iterate over it using the <> operator to retrieve the contents of the file. I must admit that when I first wrote programs that took advantage of uploading files, I was floored—could I really use the variable that I had assigned as a file handle? The answer is that it does indeed work rather well.
Trending Topics
| Make TV Awesome with Bluecop | May 16, 2012 |
| Hack and / - Password Cracking with GPUs, Part I: the Setup | May 15, 2012 |
| An Introduction to Application Development with Catalyst and Perl | May 14, 2012 |
| Cryptocurrency: Your Total Cost Is 01001010010 | May 09, 2012 |
| HTML5 for Audio Applications | May 07, 2012 |
| May 2012 Issue of Linux Journal: Programming | May 02, 2012 |
- Hack and / - Password Cracking with GPUs, Part I: the Setup
- An Introduction to Application Development with Catalyst and Perl
- Validate an E-Mail Address with PHP, the Right Way
- Make TV Awesome with Bluecop
- Monitoring Hard Disks with SMART
- Which one is the Best Free and Paid PDF editor for Mac
- Readers' Choice Awards 2011
- Examining Load Average
- Bash Regular Expressions
- Building an Ultra-Low-Power File Server with the Trim-Slice






2 hours 48 min ago
8 hours 25 min ago
11 hours 47 min ago
19 hours 34 min ago
1 day 8 hours ago
1 day 11 hours ago
1 day 17 hours ago
1 day 17 hours ago
1 day 19 hours ago
1 day 19 hours ago