Request Object | |
The Request object gives you access to the user's HTTP request header and body. It is arguably the most important built-in ASP object to understand, since it is through this object that you will be able to react to the decisions made by the user. Using the Request object, you can dynamically create web pages and perform more meaningful server-side actions (such as updating a database) based on input from the user. |
How HTTP Works | |
I will cover the Request object in detail in just a moment. First, however, it is important for you to understand the basics of the HTTP protocol. With such an introduction, use of the Request object is translated from the realm of the mysterious to the ordinary. For those of you whose eyes are beginning to glaze over, don't worry. This will be only a brief overview of the HTTP protocol. HTTP: A Simple Example You probably already know that HTTP is a "transaction"-style protocol. The browser (the client) sends a request to the server. The server obeys the request if it can and sends a response back to the client. The server then completely forgets about the transaction. The browser may or may not forget about it. HELLOCGI.HTM, an HTML page created by a CGI application To illustrate the interaction between web browser and server, let's examine
a fairly simple example that illustrates this exchange. Figure 7.1 shows Netscape Navigator displaying a very
simple form, When the user finishes entering the URL for
[73:send:(179)]GET /hello.htm HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/3.0 (Win95; I) Host: pc229.west.ora.com Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* This is a request header. The browser indicates that it wants the server to get the document /HELLO.HTM. Get is more than a generic description of what the server should do; it indicates the HTTP request type. (For details, see Section 7.1.2, later in this chapter.) The browser also indicates that it's using version 1.0 of the Hypertext Transfer Protocol. Note that a portion of the first line in this HTTP header is actually an artifact of the TCP/IP packet sniffer used in this demonstration and not part of the actual HTTP request sent. The same is true for all HTTP segments in this chapter. The server receives the headers sent by the browser, as shown in the following output produced by our spy program, and processes the request: The [21:recv: completed (179)]GET /hello.htm HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/3.0 (Win95; I) Host: pc229.west.ora.com Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* The server sends the document HELLO.HTM to the browser: [21:send:(535)]HTTP/1.0 200 OK Date: Monday, 30-Sep-98 23:33:00 GMT Server: WebSite/1.1 Allow-ranges: bytes Accept-ranges: bytes Connection: Keep-Alive Content-type: text/html Last-modified: Monday, 30-Sep-98 23:30:38 GMT Content-length: 297 <HTML> <HEAD><TITLE>Hello, World!</TITLE></HEAD> <BODY> <FORM ACTION="/cgi-win/hello.exe" METHOD="POST"> What is your name? <INPUT TYPE="text" NAME="name" SIZE=60><BR> <INPUT TYPE="submit" VALUE="Submit the form"> <INPUT TYPE="reset" VALUE="Clear all fields"> </FORM> </BODY> </HTML> Here, WebSite sends a total of 535 bytes to the browser. This consists of a response header , followed by a blank line, followed by the HTML document itself. The header fields indicate, among other things, the number of bytes (the Content-length header) and the format (the Content-type header) of the transmitted data. "200 OK" is a status code indicating that the browser's request was fulfilled. The server also indicates that, like the browser, it's using version 1.0 of HTTP. The browser reads the headers and data sent by the server: [73:recv: posted] [73:recv: completed (260)]HTTP/1.0 200 OK Date: Monday, 30-Sep-98 23:33:00 GMT Server: WebSite/1.1 Allow-ranges: bytes Accept-ranges: bytes Connection: Keep-Alive Content-type: text/html Last-modified: Monday, 30-Sep-98 23:30:38 GMT Content-length: 297 <HTML> <HEAD><TITLE>H [73:recv: posted] [73:recv: completed (275)]ello, World!</TITLE></HEAD> <BODY> <FORM ACTION="/cgi-win/hello.exe" METHOD="POST"> What is your name? <INPUT TYPE="text" NAME="name" SIZE=60><BR> <INPUT TYPE="submit" VALUE="Submit the form"> <INPUT TYPE="reset" VALUE="Clear all fields"> </FORM> </BODY> </HTML> Although two The browser displays the form asking for the user's name and, when the user fills it out and clicks the Submit button, sends the following to the server: [70:send:(232)]POST /cgi-win/hello.exe HTTP/1.0 Referer: http://pc229.west.ora.com/hello.htm Connection: Keep-Alive User-Agent: Mozilla/3.0 (Win95; I) Host: pc229.west.ora.com Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* [70:send:(69)]Content-type: application/x-www-form-urlencoded Content-length: 14 [70:send:(2)] [70:send:(16)]name=Jayne+Doe Because the browser is transmitting form data, the HTTP request type is "POST," as the very first header record indicates. Similarly, the Content-length and Content-type records indicate that the browser is transmitting 14 bytes of x-www-form-urlencoded data in the body of the request. This consists of the information input by the user in the form's single data field, the name text box. The server receives the header records and form data transmitted by
the browser in the previous step. (Since it's basically
identical to the text sent by the browser, we won't duplicate
it here.) The URL (/cgi-win/hello.exe) causes the server to
launch the CGI application The server returns the HTML document to the browser along with the necessary header records, as the following output from WSock32 Spy shows: [18:send:(422)]HTTP/1.0 200 OK Date: Monday, 30-Sep-98 23:33:10 GMT Server: WebSite/1.1 Allow-ranges: bytes Accept-ranges: bytes Connection: Keep-Alive Content-type: text/html Content-length: 231 <HTML><HEAD> <TITLE>Welcome to this Web Page!</TITLE></HEAD> <BODY><H1>Welcome to Our Web Server!</H1><p><p> Hello, Jayne Doe! We're glad that you took the time out of your busy day to visit us! <HR></PRE></BODY></HTML> Notice that the server indicates to the browser that it's sending 231 bytes of an HTML document. The browser receives the data stream sent by the server and uses it to render the HTML page. Hopefully, this gives you a fairly good sense of what's involved in the interchange between browser and server. It's important, though, to take a more in-depth look at some of the points that we've touched on only briefly, as well as to cover some additional features that are not included in this simple example. HTTP Request Types The request type is passed by the client to the server to indicate what the server should do with the URL that's also supplied by the browser. Although the HTTP specification details a number of request types, like PUT and DELETE, only two are supported by all servers and in common use: GET and POST. A GET request asks the server to "get" a piece of information, typically a document, and return it to the client. If the request includes any additional information, these are appended as arguments to the URL. A POST request, on the other hand, provides the server with information to be "posted" to the URL; typically, it's used to send the contents of an HTML form to the server, or to provide the server with information that's needed for back-end processing. The information itself is contained in the body of the request. Most servers cannot handle data received from either the POST or GET methods internally. Normally, POST requests, as well as GET requests that also send data to the server, are handled by accessory programs or DLLs (CGI and ISAPI applications and ISAPI filters). Both POST and GET requests can return any kind of data of any size. While it may seem when transmitting data to a web server that GET and POST are similar, one rule is hard and fast: A GET request must never change anything. Don't write an ASP script that makes changes to a database, for instance, in response to a GET request. The reason for this is discussed in greater detail in Section 7.1.3. Form Submission A user enters input into the fields of a form. When the form is submitted, the data contained in each field of the form is transferred to the server, which then passes it to ASP. This data is sent in the format name=value , where name is the name assigned to the field by the NAME= attribute of the <INPUT> tag, and value is the value entered in that field. For example, if the user enters "Archie" in a field prompting for his first name, the browser may send along the string first_name=Archie. If the form is written to use METHOD=GET , the form data is appended to the URL as an argument string. If the form contains many fields or if fields contain long strings of text, the complete URL can become very large and unwieldy. In addition, the limit of the number of characters submitted in a GET—typically about 2000—is much lower than in a POST. If the form instead uses METHOD=POST, the name=value pairs are sent as the body of the request instead of being appended to the URL. In addition to the greater ease of handling of POST requests, most servers offer better performance when extracting data from the body of a request than from a URL in the request header. Always use the POST method with forms that change something or cause any irreversible action (most do). POST is safer and more efficient; GET should never be used to change anything. In developing your ASP scripts, you can decide whether you want to support data passed to your program using the GET method. HTTP Request and Response Headers are the most misunderstood part of HTTP, yet understanding their role can make understanding the properties and methods of both the ASP Request and Response objects much easier. Take a look at any Internet email message. It consists of two parts, the header and the body. The header consists of several lines that describe the body of the message and perhaps the way the message was handled as it was routed to you. The header and body are separated by a blank line. (For more information on header syntax, consult RFC-822.) An HTTP message (either a request or a response) is structured the same way. The first line is special, but the rest of the lines up to the first blank line are headers just like in a mail message. The header describes the request and its content, if any, or the response and its content. The request In Section 7.1.1 we saw a number of requests from the browser. Here is another example of a simple HTTP request: POST /cgi-win/hello.exe HTTP/1.0 Accept: image/gif, image/jpeg, */* User-Agent: Mozilla/2.0N (Windows; I; 32Bit) Content-type: application/x-www-form-urlencoded Content-length: 14 The first line, which is known as the request-line, describes the type of request (or method )—in this case POST, the URL, and, finally, the version of the HTTP protocol that the client uses. The second line describes the types of documents that the client can accept. The third line is an "extra" header that's not required by HTTP. It gives the name and version of the client software. Following this, as discussed in Section 7.1.1, are two lines describing the information contained in the body of the request. Everything up to the mandatory blank line is part of the HTTP request header. In addition to the example lines here, there can be other lines in this section. For example, if the browser is sending information contained in a "cookie," that information also will be in the request header. Below the mandatory blank line is the HTTP request body. In most cases, this section of the request is empty (for example, when the browser is requesting only a static page and is not sending any information). However, when the POST method is used, the information sent to the web server is located in this section of the request. The response Here is an example of a simple HTTP response: HTTP/1.0 200 OK Date: Thursday, 02-Nov-95 08:44:52 GMT Server: WebSite/1.1 Last-Modified: Wednesday, 01-Nov-95 02:04:33 GMT Content-Type: text/html Content-length: 8151 <HTML><HEAD> <TITLE>... The first line of the response is also special and is known as the status-line. It contains the protocol version the server uses, plus a status code and a reason phrase. The server uses the status code and reason phrase to inform the browser whether it was able to respond to the browser's request; in this case, it's successfully filled the browser's request for a document. The second line contains the date and time the server handled the request. Third is a header line describing the server software and version. The fourth line indicates the date and time when the requested document was last modified. The last two lines describe the type of data and the number of bytes in the requested document. This is followed by exactly one blank line, then the body of the message, which contains the document data that the server is sending back for the browser to display. As with the HTTP request, everything above the mandatory blank line is considered part of the HTTP response header. Everything below this line is part of the response body. This chapter covers the ASP Request object, which you can use to access both the header and the body of the HTTP request. The next chapter discusses the ASP Response object, which you use in manipulating the HTTP response from the web server. The HTTP Request and the ASP Request Object As mentioned earlier, the ASP Request object allows you to access both the header and body of the HTTP request sent to the web server by the client's browser. The method of retrieving information from the HTTP request is basically the same for an ASP script as it is for a CGI application. The exceptions come not from the actual request mechanics but from how each type of application is loaded into the web server (CGI versus an ISAPI filter), as described in the first two chapters of this book. Just as with CGI applications, the client browser can send information to an ASP script in two different manners. First, it can send information by means of an HTML form using the GET method: <HTML> <HEAD><TITLE>Welcome to the Corp.</TITLE></HEAD> <BODY> <FORM ACTION=" http://mycorp.com/secure.asp" METHOD="GET"> First name: <INPUT TYPE="text" NAME="first_name" SIZE=60><BR> Last name: <INPUT TYPE="text" NAME="last_name" SIZE=60><BR> <INPUT TYPE="submit" VALUE="Submit the form"> <INPUT TYPE="reset" VALUE="Clear all fields"> </FORM> </BODY> </HTML> When the client submits a GET request, the information about the request is appended to the end of the request URL as name/value pairs separated by ampersands and preceded by a question mark. Each name corresponds to an element in the form. For example, suppose the user entered Horatia and Thompson into the two fields in the last example and clicked on the Submit button. The submission of the preceding form is, as far as the server is concerned, identical to the following: http://mycorp.com/secure.asp?first_name=horatia&last_name=thompson This is an important point. Following this example, consider the following line of code: http://mycorp.com/secure.asp?first_name=horatia&last_name=thompson If the user were to type this into the address line or click on a link containing the preceding as a URL, the web server would treat that resulting HTTP request exactly as if the information had been sent as part of a form using the GET request. From within your ASP application, you can access this information through the QueryString collection of the Request object. For example: <% strFirstName = Request.QueryString("first_name") %> will initialize the strFirstName variable to the value sent in the first_name parameter. The QueryString collection is discussed in detail later in this chapter. Just as with CGI applications, you also can send information to an ASP script using the POST method. In this case, instead of being part of the HTTP request header, the information would be in the body of the request object: <HTML> <HEAD><TITLE>Welcome to the Corp.</TITLE></HEAD> <BODY> <FORM ACTION="http://mycorp.com/secure.asp" METHOD="POST"> First name: <INPUT TYPE="text" NAME="first_name" SIZE=60><BR> Last name:<INPUT TYPE="text" NAME="last_name" SIZE=60><BR> <INPUT TYPE="submit" VALUE="Submit the form"> <INPUT TYPE="reset" VALUE="Clear all fields"> </FORM> </BODY> </HTML> This form's submission would result in an HTTP request similar to the following: POST /secure.asp HTTP/1.0 Accept: image/gif, image/jpeg, */* User-Agent: Mozilla/2.0N (Windows; I; 32Bit) Content-type: application/x-www-form-urlencoded Content-length: 35 first_name=horatio&last_name=aubrey For your application to manipulate the information sent in that HTTP request, you would have to use the Form collection of the Request object: <% strFirstName = Request.Form("first_name") %> This will initialize the strFirstName variable to the value sent in the first_name parameter. The Form collection is discussed in detail later in this chapter. |
The ASP Request Object | |
The properties, collections, methods, and events of the ASP Request object are shown in the following box. Request Object Summary
|
Comments/Troubleshooting | |
In the previous discussion of ASP and the GET and POST methods, we saw that information from a GET is retrieved by using the QueryString collection and that information from a POST is retrieved by using the Form collection. This is true, but there is a simpler way: you do not have to specify a collection. For example, the code: strName = Request("name") returns the value of the "name" key regardless of the collection in which it's located, because IIS searches all collections. When you specify a value in this manner, ASP looks through each Request object collection in the following order: QueryString Form Cookies ClientCertificate ServerVariables The variable you are initializing will receive the value in the first instance of the name/value pair whose name matches the string requested. For this reason, it is important to realize that if you have the same name/value pair in two or more collections, you will receive the first one found according to the preceding sequence, unless you specify a particular collection. As with the other collections in the ASP object model, all the collections discussed in this chapter for the Request object support the Item and Key properties, the Count method, and the For..Each construct. |
TotalBytes | |
Var = Request.TotalBytes | |
The TotalBytes property is a read-only value that specifies the total number of bytes posted to the web server by the client in the HTTP request body. This property is important when preparing to read data from the request body using the BinaryRead method of the Request object. |
|
Parameters | |
|
|
Example | |
In this example, assume that the user has responded to the following form: <HTML> <HEAD><TITLE>File Upload Form</TITLE></HEAD> <BODY> <FORM ENCTYPE = "multipart/form-data" ACTION= "http://mycorp.com/secure.asp" METHOD="POST"> Select a file to upload: <INPUT TYPE="file" NAME="filename"><BR> <INPUT TYPE="submit" VALUE="Submit the form"> </FORM> </BODY> </HTML> You can use the TotalBytes property to determine exactly how many bytes of information were sent to the web server in the HTTP request: <% ' The following code retrieves the total number of ' bytes sent in the user's HTTP request. This variable ' is then used to determine how many bytes to retrieve ' using the Request object's BinaryRead method. Dim lngTotalByteCount Dim vntRequestData lngTotalByteCount = Request.TotalBytes vntRequestData = Request.BinaryRead(lngTotalByteCount) %> |
|
Notes | |
Most often, you will not need to access data in the HTTP request body at the low level provided by the Request object's BinaryRead method and so will not need to retrieve the value of the TotalBytes property. You will use the Form and QueryString collections for almost all of your request data access. In the preceding example, the value of vntRequestData represents the total bytes sent, not just the byte count of the uploaded file; i.e., all header-related HTTP request information also counts toward this total. To retrieve from the preceding upload only the file contents, you would have to parse out the header information. |
|
ClientCertificate | |
strKeyName = Request.ClientCertificate.Key(3) strKeyValue = Request.ClientCertificate.Item(strKeyName) | |
The ClientCertificate collection of the Request object provides access to the certification fields of the client's digital certificate. Client certificates are sent to the web server when a client's browser supports the Secure Sockets Layer and that browser is connected to a web server also running the Secure Sockets Layer (i.e., the URL starts with https:// rather than http://). For example, if you were using Internet Explorer and were connected to an Internet Information Server web site with SSL running, each request made by your browser would include your client certificate, if you have one. The fields of a client certificate are specified in the International Telecommunications Union (ITU) recommendation X.509. The ClientCertificate collection, like other ASP collections, has the following properties:
As with other ASP collections, you can retrieve the value of any field of the ClientCertificate collection through the use of the Item property. Note that, because Item is the default property of the collection, the syntax can be abbreviated so that it does not explicitly show the use of the Item property. For example: strCertIssuer = Request.ClientCertificate("Issuer") is only an abbreviated form of: strCertIssuer = Request.ClientCertificate.Item("Issuer") For more information on the Item, Key, and Count properties of a collection, see the discussion in Section 4.2 in Chapter 4. The available Key values are predefined and are as follows:
You can add a "subkey" to some of the Key values to retrieve an individual subfield from either the Issuer or Subject key lists. For example, if you wanted to obtain the country of origin subkey value from the Issuer key list, you would retrieve the value: Request.ClientCertificate("IssuerC") If you wanted to retrieve the locality subkey value from the Subject key list, you would retrieve its value using the syntax: Request.ClientCertificate("SubjectL") You also can retrieve a value from a specific subkey, including those not listed here, from the Certificate key string value using the subkey's ASN.1 identifier. An ASN.1 identifier is a list of numbers separated by a period, similar in appearance to an IP address, but not limited to through 255. For example: 3.56.7886.34. The available subkeys are as follows:
|
|
Example | |
<% ' The following code retrieves the country of origin ' for the client's certificate issuer. strCertIssuerCountry = Request.ClientCertificate("IssuerC") %> <!-- #include file="cervbs.inc" --> <% ' The next example code determines whether the ' issuer is recognized by using the flags key. If Request.ClientCertificate("Flags") _ and ceUnrecognizedIssuer Then %> Your identification is in question because your issuer is not recognized. <% Else %> Welcome to our site. <% End If ' Finally, the following code iterates through the ' ClientCertificate collection and writes the key-key ' value pairs to the response buffer. For Each key In Request.ClientCertificate Response.Write "The " & key & " key contains the value " Response.Write Request.ClientCertificate(key) & "<BR>" Next %> |
|
Notes | |
Before you can retrieve information from a client's digital certificate, you must ensure that the client's web browser uses the SSL3.0/PCT1 protocol in its requests to your site. The simplest way to do this is to attempt to retrieve an element from the ClientCertificate collection. You also must ensure that you have set up your IIS web server to request client certificates. If the client sends no digital certificate, any key you attempt to retrieve from the ClientCertificate collection will be empty. The ITU Recommendation X.509 is just that—a recommendation. It has not been recognized as an official standard. For this reason, various companies' certificates may function slightly differently or may not contain all the fields you are attempting to retrieve. To ensure you are properly identifying your clients, it is wise to do some experimentation with the ClientCertificate collection before relying on it. |
|
Cookies | |
Set-Cookie: NAME=VALUE; expires=DATE; domain=DOMAIN_NAME; path=PATH; secure | |
Before
discussing the Cookies collection, we'll briefly
introduce/review the concept of HTTP cookies. This will be only a
brief overview. For more information, visit either the Netscape
Preliminary Specification at The problem with a stateless protocol like HTTP is that it forces both the server and client to do a great deal of repetitive work. For example, with a truly stateless protocol, the web server would have to ask you who you are every single time you navigate to a page on the site—even if you navigate to this new page from another page within the same site. Likewise, your interaction would be limited to what you can enter and save on one page of information, because without some way of storing the data from one page, a second page has no way of getting to that data. Netscape Communications Corp. foresaw this problem early on and devised a method by which small pieces of information could be stored by the web server on the web client's machine. This information would, in turn, be sent to the server each time the client requested a page from the same area from which she received the information. That little bit of information is at the root of Netscape's Persistent Client State Mechanism or "cookies," as they are known. (It's interesting to note that, according to the Netscape preliminary specification, this state object was called a cookie "for no compelling reason.") Through the use of cookies, web servers can store information on the client machine in a safe, easy-to-retrieve fashion that makes almost all e-commerce possible. Web sites can now keep track of who you are, when you last visited, and what type of books you like, for example. Cookies are very simple. They are sent to the client using a Set-Cookie HTTP response header in the following format (note that the Set-Cookie header should all be on one line): Set-Cookie: NAME=VALUE; expires=DATE; domain=DOMAIN_NAME; path=PATH; secure The syntax breaks down as follows:
If the user navigates to a URL for which a cookie is present on the local machine, the browser will send a Request header in the following format: Cookie:Name1=Value1;Name2=Value2;...NameX=ValueX; where:
An example will help to make this clearer. Suppose a client navigates to a URL and his browser receives the following HTTP response headers: Set-Cookie: userid=a.keyton.weissinger; domain=yourbooks.com; path=/; expires=Thursday, 10-Nov-2000 23:59:59 Set-Cookie: usersel=aspbooks; domain=yourbooks.com; path=/sales/; expires=Monday, 01-Jan-2010 23:59:59 Between now and 10 November 2000 at 11:59 P.M., the first cookie will be sent to the web server any time the client navigates to any page within any domain whose last two segments are yourbooks.com. The HTTP request header will resemble the following: Cookie: userid=a.keyton.weissinger Between now and 1 January 2010 at 11:59 P.M., the second cookie will
be sent to any page in the yourbooks.com domain whose path is
Cookie: usersel=aspbooks would be sent to http://www.yourbooks.com/sales/default.ASP or to http://www.yourbooks.com/sales/final/asp, or even to http://www.yourbooks.com/sales/checkout/default.ASP. Finally, if both sets of criteria (for both cookies userid and usersel) are met, the following cookie header will be sent by the user browser: Cookie: userid=a.keyton.weissinger; usersel=aspbooks There are several other details about cookies that you should be aware of if you plan to make extensive use of them. See either of the preceding references for more information. With this brief overview concluded, we'll now move on to the Cookies collection of the Request object. The Cookies collection of the Request object enables your ASP application to retrieve the values of cookies and cookie dictionary items from the client's HTTP request body. The Cookies collection, like the other ASP collections, has the following properties:
As with other ASP collections, you can retrieve the value of any field of the Cookies collection through the use of the Item property. Note that in the examples and explanations given here, the syntax has been abbreviated so that it does not explicitly show the use of the Item property. For example: strLastSearch = Request.Cookies("LastSearch") is only an abbreviated form of: strLastSearch = Request.Cookies.Item("LastSearch") For more information on the Item, Key, and Count properties of a collection, see the discussion in Section 4.2 in Chapter 4. In addition to storing simple values, a cookie in the Cookies collection can represent a cookie dictionary. A dictionary is a construct that is similar to an associative array in that each element of the array is identifiable by its name. However, it is important to note that although a cookie can contain a cookie dictionary, it cannot contain more complex data types, such as objects. To determine a specific value within a cookie dictionary, you must use a SubKey. For example, suppose a specific cookie represents the five colors chosen by a user on a web page. The cookie itself is called Colors and the subkeys have the following names: color1, color2, . . . color5. To determine the value residing in color3, you would use code resembling the following: strColor3 = Request.Cookies("Colors")("color3") To determine whether a specific cookie has subkeys, you must use the HasKeys property of that specific cookie, as in the following: blnHasKeys = Request.Cookies("Colors").HasKeys If blnHasKeys Then strColor3 = Request.Cookies("Colors")("color3") End If |
|
Example | |
<% ' The following code iterates through the Cookies collection. ' If a given cookie represents a cookie dictionary, then ' a second, internal for...each construct iterates through ' it retrieving the value of each subkey in the dictionary. Dim strCookie Dim strSubKey Dim str3rdCookieValue Dim strCompanyCookieValue For Each strCookie In Request.Cookies If Request.Cookies(strCookie).HasKeys Then ' The cookie is a dictionary. Iterate through it. %> The cookie dictionary <%=strCookie%> has the following values: <% For Each strSubKey In Request.Cookies(strCookie) %> SubKey: <%= strSubKey %><BR> Value: <%=Request.Cookies(strCookie)(strSubKey)%><BR> <% Next Else ' The cookie represents a single value. %> The cookie <%=strCookie%> has the following value: <%=Request.Cookies(strCookie)%> <BR> <% End If Next ' The following code retrieves the value of the third cookie ' in the Cookies collection. str3rdCookieValue = Request.Cookies(3) ' The following code retrieves the value of the "company" ' cookie in the Cookies collection. strCompanyCookieValue = Request.Cookies("Company") %> |
|
Notes | |
When accessing a cookie that represents a cookie dictionary, if you do not specify a subkey, you will retrieve a string value similar to the following: FirstSubKey=FirstSubKeyValue&SecondSubKey=SecondSubKeyValue Part of the cookie structure on the client's machine is a path representing the web page from which the client received the cookie. An important point about retrieving cookie values comes into play when two cookies with the same name, but different paths, exist. In such a case, attempting to retrieve the cookie will retrieve only the cookie from the deeper directory. For example, if the web page http://www.MyCompany.com/ContribApp/Contrib1.ASP has a cookie named UserPref and a second web page with a deeper path, for example, http://www.MyCompany.com/ContribApp/Addresses/AddrContrib1.ASP, also has a cookie named UserPref, then attempting to retrieve the UserPref cookie will retrieve only the second UserPref cookie. If you attempt to retrieve the value of a subkey for a cookie name that does not represent a cookie dictionary, the result will be null. For this reason, it is important to take advantage of the HasKeys property before attempting to retrieve the value of a subkey. As you know, the HTTP Persistent Client State Mechanism (cookies to
most people) is a continuously evolving recommendation. Any cookie
draft remains valid for only six months. The current draft, as of
this writing, can be found at From this document (or its more recent equivalent), you will learn that the latest draft for the cookies specification goes far beyond that originally proposed by Netscape. Obviously, the current Cookies collection of the Request object supports only some of this specification. It is assumed that as the draft becomes a standard, more aspects of cookies will be retrievable through the Request Cookies collection. |
|
Form | |
<FORM ACTION = "RecordPrefs.asp" METHOD = POST> Name: <INPUT TYPE = TEXT NAME = "Name"><BR> Color Pref: <SELECT NAME = "optColor"> <OPTION VALUE = "red" SELECTED>Red <OPTION VALUE = "blue" >Blue <OPTION VALUE = "green" >Green </SELECT><BR> Have a Modem? <INPUT TYPE = CHECKBOX NAME = "Modem"><BR> <INPUT TYPE=submit VALUE=submit> </FORM> | |
The Form collection allows you to retrieve the information input into an HTML form on the client and sent to the server using the POST method. This information resides in the body of the HTTP request sent by the client. The Form collection, like the other ASP collections, has the following properties:
As with other ASP collections, you can retrieve the value of any field of the Form collection through the use of the Item property. Note that in the following examples and explanations, the syntax has been abbreviated so that it does not explicitly show the use of the Item property. For example: strFirstName = Request.Form("txtFirstName") is only an abbreviated form of: strFirstName = Request.Form.Item("txtFirstName") For more information on the Item, Key, and Count properties of a collection, see the discussion in Section 4.2 in Chapter 4. |
|
Example | |
The examples of the Form collection of the Request object will all use the following HTML form: <HTML> <HEAD> <TITLE>User Information</TITLE> </HEAD> <BODY> <CENTER> <H1>User Information</H1> Please enter your user information using the form below: <FORM NAME = "frmInfo" ACTION="UserInfo.ASP" METHOD = "POST"> First Name: <INPUT TYPE="text" NAME = "txtFirstName"><BR> Last Name: <INPUT TYPE="text" NAME = "txtLastName"><BR> Zipcode: <INPUT TYPE="text" NAME = "txtZipCode"><BR> Occupation: <INPUT TYPE="text" NAME = "txtOccupation"><BR> Please select your connection speed: <SELECT NAME = "optConnSpeed"> <OPTION VALUE = "28.8" SELECTED>28.8 Modem <OPTION VALUE = "ISDN" >ISDN <OPTION VALUE = "T1" >T1 <OPTION VALUE = "T3" >T3 </SELECT><BR> Below, select all the peripherals you have: <INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE = "Joystick">Joystick<BR> <INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE= "GraphicsAccel">3D Graphics Card<BR> <INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE = "Printer">Printer<BR> <BR> Check here if it's ok to send your information: <INPUT TYPE = "checkbox" NAME = "chkSellInfo"><BR> <INPUT TYPE = "Submit" VALUE = "Submit User Info"> </FORM> </BODY> </HTML> Once the client clicks on the form's Submit button, the form information is sent to the web server via the HTTP Post method in the body of the HTTP request body. The following code could be used in <% ' The following code example demonstrates the use of ' the Form collection of the Request object to retrieve ' the values entered by the client into an HTML form. Dim strFirstName Dim strLastName Dim strZipCode Dim strOccupation Dim blnSendInfo Dim strConnSpeed Dim intPeriphCount Dim aryPeripherals( ) Dim chkItem intPeriphCount = 0 ' Retrieve the information from the form's text boxes. strFirstName = Request.Form("txtFirstName") strLastName = Request.Form("txtLastName") strZipCode = Request.Form("txtZipCode") strOccupation = Request.Form("txtOccupation") ' Retrieve the information from the Sell Information ' checkbox. blnSendInfo = Request.Form("chkSellInfo") ' Determine the connection speed from the Connection ' Speed option buttons. strConnSpeed = Request.Form("optConnSpeed") ' Populate an array with the peripherals the user has. For Each SubKey in Request.Form("chkPeriph") ReDim Preserve aryPeripherals(intPeriphCount + 1) intPeriphCount = intPeriphCount + 1 aryPeripherals(intPeriphCount) = _ Request.Form("chkPeriph")(intPeriphCount) Next %> |
|
Notes | |
If you refer to an element without an index and that element contains multiple values, your code will return a comma-delimited string. For example, suppose that instead of using a subkey with the chkPeriph element of the Form collection earlier in this chapter, we included the following line of code: response.write Request.Form("chkPeriph") Assuming we chose all three options (Joystick, GraphicsAccel, and Printer), this line of code would result in the following string: Joystick, GraphicsAccel, Printer Your application also can retrieve unparsed data from the client's HTTP request. To retrieve unparsed data from the HTTP request body, use Request.Form without any parameters. Note that the use of unparsed HTTP request data—specifically binary data—in this manner can be problematic. However, there are several ActiveX controls and Java applets that can be used to retrieve binary data more efficiently. To submit information from an HTML form to an ASP application, you must set the <FORM> tag's ACTION attribute to the name of the file that will process the HTML form data. This Active Server Page can be in the same virtual directory or can be specified in terms of its virtual directory. You can do this from an HTML page or from another ASP file. However, one of the most powerful uses of this process is the construction of an ASP that calls itself. This is not necessarily faster, but its development is more efficient. The following example demonstrates a simple ASP that constructs an HTML form whose entered data is processed by the same ASP: <% ' UserInfo2.ASP ' The following code determines whether the HTML form (see ' the bottom portion of the script) has been filled out. If ' it has, then some processing takes place and one HTML output ' is sent back to the client. If not, the HTML form is sent to ' the client. If Not IsEmpty(Request.Form("txtFirstName")) And _ Not IsEmpty(Request.Form("txtLastName")) Then ' The form has been filled out and the reply is ' a brief thank you. %> <HTML> <HEAD><TITLE>Thank You</TITLE> </HEAD> <BODY> Thank you, <%= Request.Form("txtFirstName")%>  <%= Request.Form("txtLastName")%> for your information. Have a nice day. </BODY> </HTML> <% Else %> <HTML> <HEAD><TITLE>Thank You</TITLE> </HEAD> <BODY> <FORM NAME = "frmInfo" ACTION="UserInfo2.ASP" METHOD = "POST"> First Name: <INPUT TYPE="text" NAME="txtFirstName"><BR> Last Name: <INPUT TYPE="text" NAME="txtLastName"><BR> <INPUT TYPE = "Submit" VALUE = "Submit User Info"> </FORM> </BODY> </HTML> <% End If %> This script first determines whether the form elements have been filled out by the client. If so, then this script sends a brief "Thank You" to the client and the script ends. If the information was not entered, the form is presented to the user. This technique, though it uses only a rudimentary form here, is very powerful and can significantly help you to modularize your code, a sometimes difficult task in ASP application development. If your HTML form contains ActiveX controls in addition to (or instead of) standard HTML form elements, you can refer to their values in the same manner. For example, suppose you have the following (simple) HTML form containing a single Microsoft Forms 2.0 textbox: <FORM NAME = "frmInfo" ACTION="UserInfo.ASP" METHOD = "POST"> First Name: <OBJECT NAME = "txtFirstName" WIDTH=211 HEIGHT=20 CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="MaxLength" VALUE="255"> <PARAM NAME="Size" VALUE="5574;529"> <PARAM NAME="Value" VALUE="> <PARAM NAME="BorderColor" VALUE="0"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="0"> </OBJECT> <INPUT TYPE = "Submit" VALUE = "Submit User Info"> </FORM> You could refer to the value entered into the textbox from
strFirstName = Request.Form("txtFirstName") If you have an HTML form containing ActiveX controls whose values are validated using client-side script, make sure that none of your elements (the submission button, for example) have the name Submit. This seems like a small point, but if you overlook it, you will not be able to submit your form! Try it. Remember that data in the Form collection represents only that data in the HTTP request body. You also can use the HTTP Get method to send data from the client to the server. Using Get results in the information being sent from the client in the HTTP request header. To retrieve this data, you must use the Request object's QueryString collection. |
|
QueryString | |
strKeyName = Request.QueryString.Key(3) strKeyValue = Request.QueryString.Item(strKeyName) | |
The QueryString collection allows you to retrieve the information sent by the client using the HTTP Get method with an HTML form and data appended to the URL when the page is requested. The QueryString collection is less capable than the Form collection, since there is a limit to the amount of data that can be sent in the header of an HTTP request. In my experience, this limit is around 2000 characters. More characters than this, sent as part of the QueryString, will not be processed, although the script still executes. The QueryString collection, like the other ASP collections, has the following properties:
As with other ASP collections, you can retrieve the value of any field of the QueryString collection through the use of the Item property. Note that in the following examples and explanations, the syntax has been abbreviated so that it does not explicitly show the use of the Item property. For example: strFirstName = Request.QueryString("FirstName") is only an abbreviated form of: strFirstName = Request.QueryString.Item("FirstName") For more information on the Item, Key, and Count properties of a collection, see the discussion in the Section 4.2 in Chapter 4. |
|
Example | |
<% ' This code iterates through the QueryString collection ' and fills an array with the values retrieved. Dim item Dim aryQueryValues( ) Dim intItemCount intItemCount = 0 For Each item In Request.QueryString ReDim Preserve aryQueryValues(intItemCount + 1) aryQueryValues(intItemCount) = _ Request.QueryString(item) intItemCount = intItemCount + 1 Next %> |
|
Notes | |
Like the elements of the Form collection, elements of the QueryString collection can represent multiple values. For example, suppose your ASP file receives a submission from the following HTML form: <FORM NAME = "frmInfo" ACTION="UserInfo2.ASP" METHOD = "GET"> Below, select all the peripherals you have: <INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE = "Joystick">Joystick<BR> <INPUT TYPE = "checkbox" NAME = "chkPeriph" VALUE= "GraphicsAccel">3D Graphics Card<BR> </FORM> Assume the user checks both checkboxes. The resulting information would be interpreted in the ASP exactly as if the ASP had been requested using the following URL: UserInfo2.ASP?chkPeriph=Joystick&chkPeriph=GraphicsAccel To refer to the first element, you could use the following code (note that like other ASP collections, the elements start at 1): strFirstOption = Request.QueryString("chkPeriph")(1) If you do not specify a subkey, as in: strOptions = Request.QueryString("chkPeriph") then strOptions would have the following value: Joystick, GraphicsAccel Also like the Form collection, the QueryString collection contains information sent from the client to the web server. This information can be in the form of parameter/value pairs appended to the end of the requested URL in the HTTP request header, appended to the URL in the address field of the browser, or from an HTML form whose action is set to the HTTP Get method. There are some limitations to the use of the QueryString collection, the most important of which is its limited length. Although this length varies with the amounts of client and web server available memory, you should not count on being able to send more than ~1800 characters from the client to the server using the QueryString collection. This ~1800-character "limit" is counted from the end of the script name being called to the end of the parameter list appended to the requested URL, including the names, not just the values, of the parameters sent. Like elements of the Form collection, elements of the QueryString collection can contain multiple values. To determine the number of values available for a specific element of the collection, use the Count property of the element in question. The value of the Count property is equal to the number of values contained in the element and is zero (0) if the element is not in the collection. You can retrieve all the values for a given multiple-value element by leaving off the index parameter for the specific element. The values are returned as a comma-delimited string containing only the values from the element being addressed. Also like the Form collection, you are able to retrieve unparsed data in the QueryString collection. To retrieve the raw, unparsed QueryString collection data, use the syntax Request.QueryString without any element parameter. The data in the QueryString collection is also accessible from the ServerVariables collection of the Request object, using the HTTP_QUERYSTRING parameter. This is covered in more depth in the section on the ServerVariables collection. Finally, note that you must encode several special characters when used in the QueryString:
These characters can be encoded automatically using the URLEncode and HTMLEncode methods of the Server object on the server side and custom script on the client side. |
|
ServerVariables | |
strKeyName = Request.ServerVariables.Key(3) strKeyValue = Request.ServerVariables.Item(strKeyName) | |
The ServerVariables collection contains several predefined environment variables in the context of the client's specific HTTP request of the web server. The ServerVariables collection, like the other ASP collections, has the following properties:
As with other ASP collections, you can retrieve the value of any field of the ServerVariables collection through the use of the Item property. Note that in the following examples and explanations (and in nearly all examples from other sources), the syntax has been abbreviated so that it does not explicitly show the use of the Item property. For example: strRemoteAddr = Request.ServerVariables("REMOTE_ADDR") is only an abbreviated form of: strRemoteAddr = Request.ServerVariables.Item("REMOTE_ADDR") For more information on the Item, Key, and Count properties of a collection, see the discussion in Section 4.2 in Chapter 4. The possible values for Key are in the following list. Although they typically appear in uppercase, Key is actually case insensitive. Note that like elements from other ASP collections, the element values from the ServerVariables collection also can be retrieved using an index number. However, it is important to realize that the following list is in alphabetical order, not in the order in which the elements exist in the ServerVariables collection.
|
|
Example | |
<% ' The following code determines the value of the ' LOGON_USER item of the ServerVariables collection. This ' code can be used to determine the identity of the ' client. Dim strUserName strUserName = Request.ServerVariables("LOGON_USER") %> |
|
Notes | |
As the list earlier in this section illustrates, the ServerVariables collection contains many very useful pieces of information regarding the client's HTTP request. Perhaps the most important elements allow you to determine the identity and address of the user. These elements allow you to customize your security efforts. Also, many of the Request object's other collections' data can be obtained through the ServerVariables collection (usually with more effort, however). |
|
BinaryRead | |
MySafeArray=Request.BinaryRead(ByteCount) | |
The BinaryRead method reads a number of bytes directly from the HTTP request body sent by the client as part of an HTTP Post. The data read from an HTTP request using the BinaryRead method is returned into a SafeArray. A SafeArray is a special variant array that contains, in addition to its items, the number of dimensions in the array and the upper bounds of the array. In actuality, a SafeArray is not an array at all. It's a special type of structure used internally to maintain information held in its array portion. The dimensions and upper bounds values are available only from C/C++ as elements of the structure. You cannot manipulate these values (or even retrieve them) through script. |
|
Parameters | |
|
|
Example | |
<% ' The following code determines the total number of bytes ' sent in the client's HTTP request. It then reads the ' bytes, checks for errors, and if there are none, ' reports to the client that the read was successful. Dim lngTotalByteCount Dim vntRequestData On Error Resume Next lngTotalByteCount = Request.TotalBytes vntRequestData = Request.BinaryRead(lngTotalByteCount) If Err = 0 Then ' For details about the Response object, see Chapter 8. ' For now, suffice it to say the following code sends ' information to the client. Response.Clear Response.Write lngTotalByteCount & _ " bytes successfully read.<BR>" Response.End End If %> |
|
Notes | |
If your web application's client piece could control exactly what was sent in the HTTP request body, this method would be invaluable, since it would enable your client to upload information on a byte level (or upload files). However, controlling the information sent in a Post request at byte level is difficult. There are, however, several file-transfer controls available via third parties that allow you to add file-transfer functionality to your application more efficiently and with less difficulty. It is important to note that if you have previously retrieved information from the Form collection of the Request object, subsequent calls to the BinaryRead method will cause an error. Likewise, if you have previously called the BinaryRead method of the Request object and subsequently attempt to retrieve information from the Form collection, your script will result in an error. |
|