Response Object | |
Just as the Request object allows you to retrieve and manipulate information sent by the client browser in its HTTP request, the Response object gives you a great deal of control over the HTTP response to the client. This control comes in three broad categories:
Control over the HTTP response headers includes setting cookies on the client machine, setting various preexisting HTTP header values (such as the content type and expiration information for a given page), and, finally, adding your own custom headers to the HTTP response. You control the HTTP response body directly through the Write and BinaryWrite methods. As you might infer from the names, these methods of the Response object allow you to write information directly to the response body, which will be received by the client just like any other information received in an HTML request response. Finally, the Response object allows you to control how and when the response is sent to the client. For example, using the properties and methods involved in buffering the response, you can determine whether to send the HTTP response as a single unit to the client or to send the results of the request piecemeal. You can dynamically determine whether the client is still connected to your web site. You can redirect her request as though she requested something else. Finally, you can use the Response object to write entries into the web server log. |
Buffer | |
Response.Buffer[=blnSetting] | |
The Buffer property determines whether the content created by your script is delivered to the client browser as a whole or sent immediately to the client browser as each line is created and entered into the HTML stream. If set to True, then all scripts on the page are run before the results of that script are sent to the client browser. The default value for the Buffer property is False unless you set ASPBufferingOn in the metabase (through a Windows Scripting Host script or through the Microsoft Management Console for your web site). If set in the metabase, the value there can be overridden using the Buffer property on a page. For example, if you set ASPBufferingOn to True, you could later use the Buffer property to override this behavior and force IIS not to buffer the page. |
|
Parameters | |
|
|
Example | |
Consider the following example. Note that we haven't set the Buffer property of the Response object explicitly, so it's False: <%@ LANGUAGE="VBScript" %> <HTML> <% CODE THAT RETRIEVES A FIELD VALUE FROM A DATABASE %> The response is not buffered before it is sent to the requesting browser. For this reason, if the previous database action results in an error, the user will see half a page ending in an error notice. Now examine the second code example: <%@ LANGUAGE="VBScript" %> <%Response.Buffer = True %> <HTML> <% On Error Resume Next ' CODE THAT RETRIEVES A FIELD VALUE FROM A DATABASE If Err.Number <> 0 Then Response.Clear Response.Write "There has been an error. Here is the SQL" Response.Write "statement that caused the problem: " Response.Write strSQL Response.End End If %> In this second example, the response is buffered first and completed before it is sent to the requesting browser. For this reason, we have the opportunity to clear the buffer and place a simple error notice in it that provides more information than does the unbuffered example shown earlier. The code here doesn't provide much interaction, but you get the idea. If the response is not buffered, the client will receive the HTTP response to its request as it is built—even if that building results in errors. |
|
Notes | |
The first thing to remember is that the Buffer property must be set before the <HTML> tag is generated for the HTTP response. Attempting to set the Buffer property after the <HTML> tag will result in a runtime error. If your script includes a preprocessing directive setting the language for the page, for example, this directive must be placed before you attempt to set the Buffer property's value. If you attempt to set the language for the page after setting the value for the Buffer property, you will experience an error. If the Buffer property is set to True and your script does not call the Flush method anywhere, then the web server will honor Keep-Alive requests sent by the client. Keep-Alive requests from the browser inform the server that it should maintain a connection between itself and the client. If the client's Keep-Alive request is honored on the server, it is not forced to reestablish the connection each time it makes an HTTP request. It is, in effect, already connected. This saves the client from having to resolve the URL again. If the Buffer property is set to False or if you use the Flush method somewhere in your script, the server will be forced to create a new connection to the client in response to each request. When should you buffer your scripts? The answer to this question depends on two things: how long is too long for your clients to wait, and how complex your scripts are. If your clients are introductory-level users of the Internet, their patience is typically fairly low; these clients need immediate action upon clicking the Submit button in your forms. More experienced users understand more about the back end of Internet applications and are, perhaps, more understanding of lag times in script results. More important than this is how important it is for you to present the response as a single unit. For scripts that do a great deal of iterative processing, where each loop is directly affected by the loop before, it may be important to present the final result as a single unit. However, if your script consists of several definable sections, each of which is easily capable of being displayed on its own, then buffering may be less important. One strategy for dealing with the lag times for complex scripts whose results are required in a single unit is to provide a "please wait" page in some form. This interim page informs the user that his request was received and that the script is processing. For example, suppose the client browser requests an ASP script that retrieves and formats data from a very complex query requiring a long load time (30 seconds, for example). Rather than forcing the client to click on a link and have nothing happen for 30 seconds (in which time the inexperienced web user might very well click on the same link or button repeatedly), you might first display a page like the following: <HTML> <HEAD><TITLE>Please Wait</TITLE></HEAD> <BODY LANGUAGE = "VBScript" OnLoad = "WinLoad( )"> Your request is being processed, please wait... <SCRIPT LANGUAGE = "VBScript"> Sub WinLoad( ) Parent.Location.HREF = "/Reports/Longreport.asp" End Sub </SCRIPT> </BODY> </HTML> The short page will take very little time to load, and when it does, the user will see a "please wait" message until the next script has been processed and the report is ready for viewing, at which time the "please wait" page is unloaded and the report is loaded. Finally, if you find that most of your scripts require buffering, you might consider setting the metabase ASPBufferingOn (using the App Options Configuration page for your virtual directory; see Appendix D ) so that all scripts are buffered by default. |
|
CacheControl | |
Response.CacheControl[=ProxyCacheControlSetting] | |
The CacheControl allows you to set whether proxy servers serving your pages can cache your page. If your page's content is large and doesn't change often, you might want to allow proxy servers to cache the page and thus serve it faster to requesting client browsers. |
|
Parameters | |
|
|
Example | |
Setting this property is a simple affair, as the following code demonstrates. You may be asking yourself if there is any way to determine if the client is accessing the web page through a proxy server. Although there is, if you know ahead of time of the existence of the possible proxy servers, this is problematic and cumbersome. Furthermore, there is no need to determine this before setting this property. Either the client request is being handled by a proxy server and this property will affect the caching of the page, or this property is completely ignored. <% ' The following code sets the HTTP cache control header so ' that this page can be cached by the proxy servers being ' used to access the page. Response.CacheControl = "Public" %> <HTML> <% ' Note that the CacheControl property was set BEFORE the ' <HTML> tag was constructed. %> |
|
Notes | |
Clearly, if the proxy server can cache your page, then the client's access times when accessing the page though a proxy server will be decreased. However, this is less useful if the page changes frequently. Also note that just because you set the value of the CacheControl property to Public, the proxy server is not required to cache your page(s). This must be configured on the proxy server. Setting a value for CacheControl alters the value in the cache control HTTP header sent to the client upon a request. If you use this property, you must do so before sending any response to the client (i.e., before the <HTML> tag is generated for your page). If you attempt to set the value for this (or any other HTTP header) after the <HTML> tag has already been sent to the client, an error will result unless the response is buffered. Keep in mind that setting this property does not guarantee caching on the proxy server. The proxy server itself must be configured to cache these pages before this property will have any effect. |
|
Charset | |
Response.Charset(strCharsetName) | |
The Charset allows you to specify a character set for the HTTP response content. The name of this character set is added to the end of the Content-Type header/value pair in the HTTP response headers. |
|
Parameters | |
|
|
Example | |
If you do not set the Charset property, the Content-Type HTTP response header looks like the following: content-type:text/html If you set the Charset property, as in the following line of code: <% Response.Charset("ISO-LATIN-7") %> the value you use to set the Charset property value (the string "ISO-LATIN-7" in the preceding code) is appended to the end of the Content-Type HTTP response header value: content-type:text/html;charset=ISO-LATIN-7 |
|
Notes | |
Although Charset is referred to in both this book and the Microsoft documentation as a property, it is really a method that takes a string argument representing the name of the charset to be added to the end of the Content-Type HTTP response header. For this reason, if you attempt to set the value of the Charset "property" as you would any other Response object property, you will receive an error: <% ' Next line will NOT work: Response.Charset = "ISO-LATIN-7" %> If the value you set for the Charset property does not represent a valid character set, this value is ignored by the client's browser, and the default character set is used instead. Note that you can append the name of only one character set to the end of the Content-Type header/value pair. Each subsequent change of the Charset property's value simply replaces the last setting. For example, the following code: <% Response.Charset("ISO-LATIN-7") Response.Charset("ISO-LATIN-3") %> results in the following Content-Type HTTP response header/value pair: content-type:text/html;charset=ISO-LATIN-3 Also note that if your content type is exclusively nontext (image data, for example), the character set value is ignored by the browser. Finally, the default character set for the Apple Macintosh and compatibles is not ISO-LATIN-1, as it is for IBM PCs and compatibles. If you do not set the Charset property, all Macintosh browsers will interpret requested pages to be in the Macintosh character set. Microsoft's Personal Web Server for Macintosh automatically converts the character set of the requested content to ISO-LATIN-1 and will ignore any other Charset property settings you provide in your script. Like other properties that result in a change to the HTTP response header values, the Charset property must be set before the server sends the <HTML> tag to the client unless the response is buffered. |
|
ContentType | |||||||||||||||||||||||||
Response.ContentType[=strContentType] | |||||||||||||||||||||||||
The ContentType allows you to set the value for the Content-Type setting in the HTTP response header. This value defines the type of data being sent in the Response body. The client browser uses this information to determine how to interpret downloaded HTTP response content. |
|||||||||||||||||||||||||
Parameters | |||||||||||||||||||||||||
|
|||||||||||||||||||||||||
Example | |||||||||||||||||||||||||
<% ' The following code sets the value of the Content-Type ' HTTP response header according to the value of a ' local variable. If strData = "jpg" Then Response.ContentType = "image/JPEG" Else Response.ContentType = "text/plain" End If %> |
|||||||||||||||||||||||||
Notes | |||||||||||||||||||||||||
Some of the possible values for ContentType type/subtype pairs are listed in Table 8.1.
The number of subtypes is expected to grow significantly over time. The best reference for the available subtypes is the latest MIME RFC (RFC 2231 as of this writing). Many of the new subtypes are expected to come from industry. For example, Microsoft has already added the x-cdf subtype to the application type for its Channel Definition Format. Like other properties that result in a change to the HTTP response header values, the ContentType property must be set before the server sends the <HTML> tag to the client unless the response is buffered. As another example of the ContentType property, see the code example for the Response object's BinaryWrite method later in this chapter. |
|||||||||||||||||||||||||
Expires | |
Response.Expires[=intNumMinutes] | |
The Expires property specifies the length of time (in minutes) that the client machine will cache the current page. If the user returns to the page within the amount of time set for the Expires property, the user will view the cached version of the page. If the Expires property is not set, content expiration set for the virtual directory (through the Properties page for the virtual directory on the Microsoft Management Console) will be used. Its default is 24 hours. |
|
Parameters | |
|
|
Notes | |
If you wish to prevent the client's browser from caching the page, use a value of for intNumMinutes. Doing so will force the client to rerequest the page from the web server every time the client navigates to the page. If you attempt to set the Expires property more than once in a script, the shortest setting is used. For example, the page that includes the following script will result in the client caching the page for five minutes, even though the last setting of the Expires property is 20 minutes: <% Response.Expires = 10 Response.Expires = 5 Response.Expires = 20 %> Like other properties that result in a change to the HTTP response header values, the Expires property must be set before the server sends the <HTML> tag to the client unless the response is buffered. |
|
ExpiresAbsolute | |
Response.ExpiresAbsolute[=[ Date ] [ Time ] ] | |
Specifies a date and time on which the content of the current page will cease being cached on the client machine. If no time is specified when setting the ExpiresAbsolute property, the time is taken to be midnight on the date specified. Before the date specified in the ExpiresAbsolute property, the client will display the cached version of the current page if the user navigates to it. |
|
Parameters | |
|
|
Example | |
<% ' The following code sets the current page's caching on the ' client machine to end at 9 P.M. on 7 May 1998 GMT. NOTE ' the use of the "#" to designate the date and time. Response.ExpiresAbsolute=#May 7, 1998 21:00:00# %> |
|
Notes | |
As the example demonstrates, you must use the pound character (#) to designate the date and time used in the ExpiresAbsolute property value. Like the Expires property, setting this property multiple times results in the current page's caching ending on the earliest date and time specified in the script. Like other properties that result in a change to the HTTP response header values, the ExpiresAbsolute property must be set before the server sends the <HTML> tag to the client unless the response is buffered. |
|
IsClientConnected | |
Response.IsClientConnected | |
A read-only property that evaluates to True if the client is still connected to the web server since the last use of the Response object's Write method and returns False otherwise. |
|
Parameters | |
None |
|
Example | |
<% ' The following code determines whether the client ' is still connected to the server. If it is still ' connected, then the SessionID (see Chapter 10) will be ' used to retrieve the user information from a database. If Response.IsClientConnected Then strUserName = fn_strGetUserName(Session.SessionId) End If %> |
|
Notes | |
The IsClientConnected property gives you the ability to determine whether the client has disconnected. This is very important if the current script is long. If the client is no longer connected, it may be important to discontinue processing a script. The following example demonstrates checking for the client connection before continuing in a long script. If the client is no longer connected, the easiest way to stop all processing is to use the Response object's End method. <%Response.Buffer = True%> <HTML> <HEAD><TITLE>One Long Script</TITLE></HEAD> <BODY> <% ' The following code is the first of two segments ' in this script that will take a long time to process: [SOME LONG CODE] ' Now before performing the second half of this long script, ' check to see if the client is still connected. If Response.IsClientConnected Then [SECOND LONG CODE SEGMENT] Else ' The client is no longer connected, end the script's ' processing. Response.End End If %> </BODY></HTML> This property is useful only for those clients using HTTP 1.1. If the browser uses HTTP 1.0, IIS tracks the session using individual HTTP requests and Keep-Alive requests by the client, not a constant connection that is only consistent with the later (1.1+) version of HTTP. If your ASP file in which you use IsClientConnected is running under IIS 4.0, then the property value is only accurate if the file sends content to the client (i.e., if it is a file containing only server-side code, the resulting value of IsClientConnected is not correct). However, in IIS 5.0, IsClientConnected works regardless of whether or not the current file sends content to the client. |
|
PICS | |
Response.PICS(strPICSLabel) | |
Adds a PICS (Platform for Internet Content Selection) label to the HTTP response header. This PICS system labels your web content to enable rating services (such as the Recreational Software Advisory Council (RSAC) and SafeSurf, a parents' organization) to rate that content according to various criteria set by content control software such as NetNanny and CyberWatch. |
|
Parameters | |
|
|
Example | |
<% ' The following piece of code sets a PICS label for the ' content of this page corresponding to the rating discussed ' earlier. Dim strPicsLabel strPicsLabel = _ "(PICS-1.1 <HTTP://www.rsac.org/ratingsv01.html> " strPicsLabel = strPicsLabel & "labels on " & Chr(34) strPicsLabel = strPicsLabel & "2000.07.20T06:00-0000" & _ Chr(34) strPicsLabel = strPicsLabel & " until " & Chr(34) strPicsLabel = strPicsLabel & "2000.12.31T23:59-0000" & _ Chr(34) strPicsLabel = strPicsLabel & "ratings (V 0 S 1 L 3 N 0))" Response.PICS(strPicsLabel) %> |
|
Notes | |
The PICS label in the example states that:
The actual PICS label that is added to the HTTP response header is the following: PICS-label:(PICS-1.1 http://www.rsac.org/ratingsv01.html labels on "1998.03.20T06:00-0000" until "1999.12.31T023:59-0000" ratings (v 0 s 1 l 3 n 0)) If you attempt to add an invalid PICS label to the HTTP header, the client machine will ignore it. Note that each subsequent setting of the PICS property value overwrites the last value. Only the final setting is actually sent to the client machine. Note also that the dates in the PICS label are in quotation marks. For this reason you must use the Chr(34) character (34 is the ASCII equivalent to the quotation mark). This is easiest to handle by simply typing out the label as it should appear in the final PICS label and then replacing each quotation mark in the line of code with the following: " & Chr(34) & " Like other properties that result in a change to the HTTP response header values, adding a PICS label must be done before the server sends the <HTML> tag to the client unless the response is buffered. |
|
Status | |
Response.Status(strStatusDescSetting) | |
Specifies the HTTP status line that is returned to the client machine from the web server. |
|
Parameters | |
|
|
Example | |
<% ' The following code sets the Status property of the ' Response object to 404 Not Found. Unless other content is ' generated for the page, the status code will be ' interpreted by itself by the client. strStatusText = _ "404 Not Found The Web server cannot find the " strStatusText = strStatusText & "file or script you asked " strStatusText = strStatusText & "for. Please check the URL " strStatusText = strStatusText & "to ensure that the path " strStatusText = strStatusText & "is correct." Response.Status = strStatusText %> |
|
Notes | |
As with setting other Response headers, each subsequent setting of the Status property value resets the last setting. Like other properties that result in a change to the HTTP response header values, the Status property must be set before the server sends the <HTML> tag to the client unless the response is buffered. |
|
Cookies | |
strKeyName = Response.Cookies.Key(3) strKeyValue = Response.Cookies.Item(strKeyName) | |
The Cookies collection of the Response object enables your ASP application to use the Set-Cookie HTTP response header to write cookies to the client's machine. If you attempt to set the value of a cookie that does not yet exist, it is created. If it already exists, the new value you set overwrites the old value already written to the client machine. As with the Cookies collection of the Request object, each cookie in the Cookies collection of the Response object can also represent a cookie dictionary. Recall from Chapter 7, that a cookie dictionary is a construct that is similar to an associative array in that each element of the array is identifiable by its name. For more information on cookie dictionaries, see the section on the Cookies collection of the Request object in Chapter 7. The Cookies collection of the Response object, like 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. However, as in other places in this book, in the following examples, the syntax has been abbreviated so that it does not explicitly show the use of the Item property. For example: Response.Cookies("UserPref") = "Red" is an abbreviated form of: Response.Cookies.Item("UserPref") = "Red" To set the value of a cookie, you would use code similar to the following: Response.Cookies("LastSearch") = _ "SELECT * FROM Details WHERE Color = 'Red'" For more information on the Item, Key, and Count properties of a collection, see the discussion in Section 4.2 in Chapter 4. The previous code would create the cookie UserPref if it doesn't already exist (or overwrite the original value if it does). This cookie would translate into a SET-COOKIE response header being added to the response sent back to the client browser. The client browser would receive this response header and create (or overwrite) a UserPref cookie on the user machine. Each element in the Cookies collection (or subkey, if the cookie is a cookie dictionary) also has the following cookie-specific attributes:
|
|
Example | |
The following is a more complete example of the use of the Cookies collection of the Response object. It demonstrates many of the items discussed earlier. <HTML> <HEAD><TITLE>Search Cookie Example</TITLE></HEAD> <BODY> <H3>Welcome to the Search Results Options Page.</H3> You can use the following form to select your search results display options. These options will be saved on your machine as a set of cookies. <FORM ACTION="/SaveSearchCookie.asp" METHOD = POST> First Name:<INPUT TYPE = TEXT NAME = "txtFirstName"><BR> Last Name:<INPUT TYPE = TEXT NAME = "txtLastName"><BR> User ID:<INPUT TYPE = TEXT NAME = "txtUserId"><BR> Check All that Apply: Show Descriptions: <INPUT TYPE = CHECKBOX NAME = "chkUserPrefs"VALUE = "Desc"> Show Hit Count (display how many matches found per result): <INPUT TYPE = CHECKBOX NAME = "chkUserPrefs"VALUE = "Count"> Show Relevance with Graph: <INPUT TYPE = CHECKBOX NAME = "chkUserPrefs" VALUE = "Graph"> Use Small Fonts(will show more results per page): <INPUT TYPE = CHECKBOX NAME = "chkUserPrefs" VALUE = "Small"> <INPUT TYPE = SUBMIT VALUE = "Save Selections"> </FORM> </BODY> </HTML> The following code ( <% ' The following code retrieves user information from the ' Form collection of the Request object (see Chapter 7) and ' then writes the information to a set of cookies on the ' client machine. Dim strFirstName Dim strLastName Dim strUserId Dim intCounter Dim intPrefCounter Dim strKeyName Dim arstrUserPrefs( ) ' Retrieve user information... strFirstName = Request.Form("txtFirstName") strLastName = Request.Form("txtLastName") strUserId = Request.Form("txtUserId") intPrefCounter = 1 For intCounter = 1 to Request.Form("chkUserPrefs").Count ReDim Preserve arstrUserPrefs(intPrefCounter) arstrUserPrefs(intPrefCounter - 1) = _ Request.Form("chkUserPrefs")(intCounter) intPrefCounter = intPrefCounter + 1 Next ' Write the user information to the client machine. ' Save all the information in cookies, but set the ' Expires property only for the UserId. We'll want ' that to remain on the client machine after the session ' is complete. Response.Cookies("UserFirstName") = strFirstName Response.Cookies("UserLastName") = strLastName For intCounter = 1 to intPrefCounter - 1 strKeyName = "Pref" & CStr(intCounter) Response.Cookies("UserPrefs")(strKeyName) = _ arstrUserPrefs(intCounter - 1) Next ' Note in the first line below, that when no property ' is specified, the value of the cookie is set. Response.Cookies("UserId") = strUserId Response.Cookies("UserId").Expires = #December 31, 1999# Response.Cookies("UserId").Domain = "www.customsearch.com" Response.Cookies("UserId").Path = "/usersearch/" Response.Cookies("UserId").Secure = True %> |
|
Notes | |
In the example, the UserFirstName cookie is sent to the client machine. For this example, let's assume the value of the strFirstName variable is the string "David." The actual HTTP response header sent to the client machine is: Set-Cookie:USERFIRSTNAME=david Also for this example, assume the three values sent are 800 (for client browser width), 8 (for color depth in bits), and English (for English language preference). The actual HTTP response header sent to the client is the following: Set-Cookie:USERPREFS=PREF1=800&PREF2=8&PREF3=english If the string value sent for a value of a cookie contains spaces, those spaces are replaced with plus signs (+) in the HTTP response header. If you sent a subsequent cookie value to the UserPrefs cookie on the client machine without specifying a SubKey, as in the following: Response.Cookies("UserPrefs") = "german" the two values for PREF1 and PREF2 will be overwritten and the Count property for the UserPrefs cookie will return 1. Alternatively, if you send a subsequent cookie value and specify a SubKey to a client machine where the cookie has a value but no keys, the value already in place on the client machine is overwritten. If, while you are generating values for the Cookies collection of the Response object, you need to determine if there are already subkeys defined for a given cookie, you can evaluate the HasKeys property of the cookie. If the cookie has subkeys defined, the HasKeys property evaluates to True. Like other properties that result in a change to the HTTP response header values, the Cookies collection values must be set before the server sends the <HTML> tag to the client unless the response is buffered. |
|
AddHeader | |
ClientCustomHeader:CustomHeaderValue | |
Allows you to add your own HTTP response header with a corresponding value. If you add an HTTP header with the same name as a previously added header, the second header will be sent in addition to the first; adding the second header does not overwrite the value of the first header with the same name. Also, once the header has been added to the HTTP response, it cannot be removed. If the client sends the web server an HTTP header other than those listed in the section on the ServerVariables collection in Chapter 7, you can use HTTP_HeaderName to retrieve it. For example, if the client sends the HTTP header: ClientCustomHeader:CustomHeaderValue then you could retrieve the value for this element using the following syntax: <% Request.ServerVariables("HTTP_ClientCustomHeader") %> This is an advanced method and should not be used without careful planning. If another method of the Response object will meet your needs, use it instead of using the AddHeader method. |
|
Parameters | |
|
|
Example | |
<% ' The following code adds the CUSTOM-ERROR HTML header to ' the HTTP response headers. Response.AddHeader "CUSTOM-ERROR", "Your browser is not IE." %> |
|
Notes | |
Like the other methods and properties of the Response object that alter the HTTP response headers, you must call the AddHeader method before sending the <HTML> tag to the client. If you have previously set the Buffer property value of the Response object to True, you can use AddHeader unless you have previously called the Flush method. If you call AddHeader after sending the <HTML> tag to the client or calling the Flush method, your call to AddHeader will result in a runtime error. You should not use underscores in your custom headers. Doing so will increase your chances of ambiguity with headers already present. Use hyphens to separate multiple words instead. Also, note that to retrieve the value of a custom header with hyphens, you replace them with underscores when retrieving the values of your custom headers. |
|
AppendToLog | |
Response.AppendToLog strLogEntry | |
Adds a string to the web server log entry for the current client request. You can only add up to 80 characters at a time, but you are able to call the AppendToLog method multiple times. |
|
Logging web site activity | |
IIS allows you to log user activity into a text file or into an ODBC-compliant database. This logging is separate from Windows NT logging, and the records in the IIS log cannot be viewed using the Windows NT Event Viewer tool. To view the IIS log files, you must open them as you would any other ASCII text file, import them into a spreadsheet or database program, or, if you've been logging to an ODBC database, view them through queries to that database. The log files for IIS are found in
Specifically, you can log the following aspects of users' visits to your web site, among other things:
Using this information and information your application adds to this log through Response.AppendToLog, you can plan future development for your site, plan security, and plan for new servers if the load warrants it. |
|
Parameters | |
|
|
Example | |
<% ' Assume you have constructed one string containing all that ' you'd like logged to the web's server. This string is ' declared as strOrigLogContent. The following Do...While ' loop code will loop through your content and log it to the ' web server 79 characters at a time. Do While Len(strOrigLogContent) > 0 If Len(strOrigLogContent) >= 79 Then strLogString = Left(strOrigLogContent, 79) Else strLogString = strOrigLogContent End If ' Log the content. Response.AppendToLog strLogString If Len(strOrigLogContent) > Len(strLogString) Then strOrigLogContent = _ Right(strOrigLogContent, _ Len(strOrigLogContent) - Len(strLogString)) Else strOrigLogContent = " End If Loop %> |
|
Notes | |
Before you are able to append information to the web server log in IIS, you must enable the URL Query option of the Extended Logging Properties sheet for the web site whose activity the log files are being used to record. This method can be an invaluable time saver in maintaining detailed information about actions on your web site. If you have a unique identifier for each user that is stored in the log file with the entry (which contains an IP address, possibly a Windows NT account name, and the date and time of the visit), you can quickly determine who was visiting the site at the time of an unexpected error on your site. This method cannot be relied on for security, since you cannot be 100% certain of the user's identity, but it can help. |
|
BinaryWrite | |
Request.BinaryWrite arbyteData | |
Writes information directly to the response content without any character conversion. If your application involves writing binary data to the client, you must use this method to ensure that data you send is not converted to character data from the original binary. |
|
Parameters | |
|
|
Example | |
The following example code is lengthy for the simple call to BinaryWrite, but it demonstrates a very useful concept, especially if you are forced to deal with binary data from a database. <% ' The following code retrieves a binary object ' (in this case a JPG image) and writes it to the ' client using BinaryWrite. (For more information ' on ActiveX Data Objects usage, see Chapter 12.) ' Create an ADO connection object. Set adoCon = Server.CreateObject("ADODB.Connection") ' Use the Open method of the Connection object ' to open an ODBC connection with the database ' represented by the DSN ImageDatabase. adoCon.Open "ImageDatabase" ' Use the Execute method of the ADO Connection object ' to retrieve the binary data field from the database. Set adoRecImgData = adoCon.Execute _ ("SELECT ImageData FROM Images WHERE ImageId = 1234") ' Create a Field object by setting one equal to a ' specific field in the recordset created previously. Set adoFldImage = adoRecImgData("ImageData") ' Use the ActualSize property of Field object to retrieve ' the size of the data contained in the Field object. After ' this line you will know how many bytes of data reside in ' the Field object. lngFieldDataLength = adoFldImage.ActualSize ' Use the BinaryWrite method to write 4K bytes of binary ' data at a time. So, first we need to determine how many ' 4K blocks the data in the Field object represents. lngBlockCount = lngFieldDataLength / 4096 ' Now let's get how many bytes are left over after removing ' lngBlockCount number of bytes. lngRemainingData = lngFieldDataLength Mod 4096 ' We now must set the HTTP content type Response header ' so that the browser will recognize the data being sent ' as being JPEG image data. Response.ContentType = "image/JPEG" ' Loop through and write the first lngBlockCount number ' of binary blocks of data. For intCounter = 1 to lngBlockCount Response.BinaryWrite adoFldImage.GetChunk(4096) Next ' Now write the last remainder of the binary data. Response.BinaryWrite adoFldImage.GetChunk(lngRemainingData) ' Close the recordset. adoRecImgData.Close %> |
|
Notes | |
At first, the BinaryWrite method seems to be of limited use, until you have binary data stored in a database that must be sent to the client; then, BinaryWrite is invaluable. As the code sample demonstrates, one example of this is the display of image data that is stored and retrieved from a DBMS capable of storing binary data. I have used this method to display JPEG images stored in a Microsoft SQL Server database (using code similar to the preceding), and it works quite well. Because you are sending the HTTP response containing only the image data (not a link request to the image), it may even be faster than sending images to the client upon a straight client request, assuming your database access is suitably fast. |
|
Clear | |
Response.Clear | |
Empties the current contents of the Response buffer. It does so without sending any of the buffered response to the client. |
|
Parameters | |
None |
|
Example | |
<% Response.Buffer = True%> <HTML> <HEAD><TITLE>Response Clear Method Example</TITLE></HEAD> <BODY> <% On Error Resume Next [CODE TO DO SOME CALCULATIONS] lngFormulaElement1 = 47 lngFormulaElement2 = lngFormulaElement1 - 47 lngFormulaElement3 = 23 ' This next line results in a division-by-zero error ' (Error Number 11). lngNewCalcTotal = lngFormulaElement3 / lngFormulaElement2 ' This next line will still be processed because we used ' ON ERROR RESUME NEXT. If Err <> 0 Then ' The following code clears the Response buffer, writes ' an error message, and ends the response, forcing IIS to ' send the response to the client. Note that the Buffer ' property has to be set to True for the following code ' to work properly. Response.Clear Response.Write "Your request resulted in the error: " & _ Err.Description Response.Write " Error Number: " & Err.Number Response.Write "<BR>Call your web admin at 555-HELP for " Response.Write "more information." Response.End End If %> |
|
Notes | |
The Clear method of the Response object does not clear any HTTP headers, only the content. As noted in the example, the Buffer property of the Response object must be set to True or the use of this method will result in a runtime error. One of the most important uses for the Clear method is to clear the buffer and send to the client browser something else instead, often error information, as is the case with the example. For errors to be caught and error information to be sent to the client in this fashion, not only must the Buffer property be set to True, but also you must use the following line of code to ensure that your error trap will be processed: On Error Resume Next |
|
End | |
Response.End | |
Ends all storage of information in the response buffer and sends the current contents of the buffer immediately to the client. Any code present after the call to the End method is not processed. Any memory set aside by the script up until the call to End (such as database objects previously used in the script) is released. |
|
Parameters | |
None |
|
Example | |
See the previous example for the Clear method. |
|
Notes | |
If the Buffer property is set to True, calling the End method will flush the Response buffer exactly as if you had called the Flush method (see the next section). However, unlike calling the Flush method, no code after the call to End is processed by the web server. |
|
Flush | |
Response.Flush | |
Immediately sends all data currently in the response buffer to the client. Unless the Buffer property of the Response object is set to True, this method will result in a runtime error. This method allows you to send various portions of the response to the client at your discretion. |
|
Parameters | |
None |
|
Example | |
<% Response.Buffer = True%> <HTML> <HEAD><TITLE>Response Flush Method Example</TITLE></HEAD> <BODY> <% ' Suppose for this example that this first part of the ' script retrieves some information from a database and ' that retrieval takes a long time, say 30 seconds. ' (Don't worry about the details of the ActiveX Data Object ' calls. They are covered later in the book and serve only ' as an example here of something that might take a long time.) Set adoCon = Server.CreateObject("ADODB.Connection") adoCon.Open MyDatabase Set adoRec = adoCon.Execute([BIG SQL STATEMENT]) ' Rather than continue to the second part of the script, in ' which a second slow SQL statement (say another 15 seconds) ' executes, first we'll use the Flush method to force the ' first part of the script results to the client. This way, ' the user can be looking at the results of the first query ' while waiting for the second. Response.Flush ' [Second LONG SQL statement.] Set adoRec2 = adoCon.Execute([BIG SQL STATEMENT]) %> </BODY></HTML> |
|
Notes | |
Using the buffering capacity of the Response object, you are able to send the response to the client in parts. For example, suppose you are presenting a description of your worldwide organization followed by a list of offices derived from information in a database. The organization description is straight text, and thus it takes very little time to prepare and send it to the client. The second part takes more time. You could use the Flush method of the Response object to send the organizational description to the client first and then send the list when it is complete. Without this approach, the user can get the impression that the page is slow to download. One caution, however: if you use the Flush method on an Active Server Page, the server will ignore Keep-Alive requests sent by the client for that page. This will force a new connection to be made for each piece of information sent to the client. |
|
Redirect | |
Response.Redirect strURL | |
Redirects the client's request to another URL. |
|
Parameters | |
|
|
Example | |
<% ' The following code determines whether the client has ' security clearance for a certain page. If not, it ' is redirected to another URL. [...Code to determine user's clearance for the current page...] If Not(strUserSecurity = "ADMIN" or strUserSecurity = "SUPERADMIN") Then Response.Redirect "/security/noclearance.asp?usrid=09563" End If %> |
|
Notes | |
The strURL value you use when calling the Redirect method can be an exact URL with DNS or a virtual directory and filename. It also can be the name of a file that resides in the same folder as the requested page. If your script has written any content to the HTTP response body, that content is ignored by the script once the call to the Redirect method is executed. Calling the Redirect method is conceptually the same as setting the Status property to "302 Object Moved" and sending the user to a new location using the Location HTTP header. Note that upon redirection, some older (HTTP 1.0) client browsers will mistakenly change POST requests to GET requests when the new URL is called. This is an important consideration when the client's POSTed information contains more data than the GET method can handle. It is assumed that new browsers supporting the HTTP 1.1 protocol have fixed this problem. If your ASP file is running under IIS 5.0, you should consider using the Server method Execute or Transfer. Neither of these methods involve the costly trip to the client and back to the server that Redirect requires. |
|
Write | |
Response.Write vntData | |
Writes information directly to the HTTP response body. |
|
Parameters | |
|
|
Example | |
<% strDirCommand = "Dir /w" ' The following code writes an entire HTML table to the HTTP ' response body. Response.Write "<TABLE>" Response.Write "<TR>" Response.Write "<TD WIDTH = 50%\>" Response.Write "Command" Response.Write "</TD>" Response.Write "<TD WIDTH = 50%\>" Response.Write "Description" Response.Write "</TD>" Response.Write "</TR>" Response.Write "<TR>" Response.Write "<TD WIDTH = 50%\>" Response.Write Chr(34) & strDirCommand & Chr(34) Response.Write "</TD>" Response.Write "<TD WIDTH = 50%\>" Response.Write "This allows you to see a list of the " Response.Write "files in <BR> your current folder." Response.Write "</TD>" Response.Write "</TR>" Response.Write "</TABLE>" %> |
|
Notes | |
As demonstrated in the example program, you can use the Write method to write HTML and client-side script to the response body that the client browser will interpret as plain HTML. To send a carriage return/line feed or a quotation
mark, use the ' Note: Chr(34) is a quotation mark. Chr(13) & Chr(10) is ' the equivalent of a carriage return, followed by a ' linefeed. Response.Write "Hamlet said, " & Chr(34) & _ "To be, or not to be." & Chr(34) & Chr(13) & Chr(10) Finally, you can use the Write method to send the value of a server-side script to the client browser. This method is sometimes cleaner in your code than going back and forth between server-side code and client code using the <%=...%> notation. For example, the following code displays the value of the strHighestPrice data value using both the <%=...%> and the Response.Write methods: %> <% Response.Write "The highest price is " & strHighestPrice Response.Write ".<BR>" ' The same line as the preceding using the other format: %> The highest price is <%=strhighestPrice%>.<BR> |
|