The ASP Emporium
Free Active Server Applications and Examples by Bill Gearhart
Online since Friday January 7, 2000

 home > code > tutorials > Downloading Files with VBScript and ASP

enter a phrase to search: (advanced search)


 h o m e 

 w h a t 's  n e w 

 a l l   c o d e 
  .net:
    • Fundamentals
    • C# Classes
  classic asp:
    • Code Library
    • ASP Apps
  general:
    • Tutorials
    • SQL

 d o w n l o a d s 

 u s e r   f o r u m s 

 l i n k s 

 s e a r c h 

 s u p p o r t 


Downloading Files with VBScript and ASP

Setting up a simple file downloading system with VBScript and ASP is no sweat. This system can be tested by downloading a classic ASP app

The primary use for a system like this is to allow downloading of any TEXT based file that would normally be served via a client's browser and be unable to be downloaded. This system works great when setting up downloads for files with the following extensions: *.txt, *.htm, *.html or *.asp . This system won't work to serve binary files such as images.

A secondary use is to allow download access to directories outside the public server space or a hidden directory within the website. This system can also be used in conjunction with the fileupload class to let users download uploaded content without allowing direct access to the upload directory.

sample directory setup

To make this system easier to understand, assume you have a website structure like the one displayed at left. Everything in the download folder is a text based file that the NT box hosting this website will serve as HTML. The catch is you don't want to serve the files in the download directory, you want them to be downloaded just like they were *.zip or other similar files.

VBScript and ASP can work together to create a simple download system that can serve TEXT based files as downloadables. But you should be warned that this system doesn't work so well with PWS. It is meant for an NT or Win 2k system. PWS doesn't send and obey content-types as well as NT. I will try to further explain this later...

This setup requires you to create two files. The first, called index.asp is responsible for scanning the downloads directory and creating links to the second file. The second file is called download.asp and performs the actual download of the file name passed to it by index.asp.

index.asp

index.asp is responsible for scanning the downloads directory. To achieve this we will use the standard workhorse, the Scripting.FileSystemObject to retrieve the files in a directory and output the file names and paths as options in a select box. When the form is submitted, the file name and path of the selected file is passed to the second page in the package: download.asp, which serves the file as a content type that will trigger any web browser to download the file instead of displaying it.

index.asp looks like this:

<%
dim fso, fldr, file, strDownloadDirectory

 ' this is the download folder's path.
 ' everything to be downloaded is in this folder
strDownloadDirectory = Server.mappath("/downloads/")

 ' create a simple form to allow a user to choose a file
 ' for download...
response.write "<FORM METHOD=GET ACTION=""./download.asp"">" & vbCrLf
response.write "<SELECT NAME=""file"">" & vbCrLf

set fso = server.createobject("scripting.filesystemobject")
set fldr = fso.getfolder(strDownloadDirectory)
for each file in fldr.files
	 ' loop through each file in the download folder
	response.write "<OPTION VALUE=""" & strDownloadDirectory & _
		"\" & file.name & """>" & file.name & "</OPTION>" & vbCrLf
next

 ' free memory
set fso = nothing
set fldr = nothing
set file = nothing

 ' and finish the form
response.write "</SELECT>" & vbCrLf
response.write "<INPUT TYPE=SUBMIT VALUE=""download file"">"
response.write "</FORM>" & vbCrLf
%>

Index.asp makes a form similar to this (depending on what's inside the download folder):

Each option contains the complete path to the download file which is then passed to the second page, download.asp

download.asp

download.asp cannot be accessed directly because it needs to be passed information about the location of a file to download. After download.asp receives a fully-qualified path to a file, two things happen.

First, the file path is passed to a simple function that reads the chosen file. Since we are using the Scripting.FileSystemObject, there can be no BINARY files requested, only TEXT files (there is no Dana, only Zool...). The FSO reads and saves the file as a string into a variable that is passed out by the function.

So far everything is pretty simple. Right now the file requested has been gathered into memory. The second part of download.asp is what makes the actual download happen. Most files, including *.asp files, when requested by a browser output a content-type header of text/html which makes the browser parse and show the document. To get a download to happen instead you need to change the Content-Type header of the document to one that triggers a download.

The best Content-Type to use is application/octet-stream. Most other content-type headers will cause problems for IE's security zones. The application/octet-stream Content-Type tells the browser that this file cannot be read and the client should be asked what to do with the file. For IE this means download. Netscape will probably give you some choices in addition to downloading the file but at least the choice is there.

So now the file will be downloaded but let's get the file name and display it in the save dialog box that comes up. We achieve this by adding another header to the file to download. This second header is the Content-Disposition header which can contain the filename of the document.

Now that everything is setup to download, all you need to do is write the contents of the variable holding the page to the browser and it will download! This will become more clear once you see the source code for download.asp


<%
Option Explicit
Response.Buffer = True


Function FileRead(byVal FILE)
	 ' this function reads a file's contents
	Dim strOut : strOut = ""
	Dim objFSO, FileDownload
	Set ObjFSO = Server.CreateObject("Scripting.FileSystemObject")
	Set FileDownload = ObjFSO.OpenTextFile(FILE, 1, False)
	strOut = FileDownload.ReadAll()
	FileDownload.Close
	Set FileDownload = Nothing
	Set objFSO = Nothing
	FileRead = strOut
End Function


Dim strFileToDownload, strFileContents

 ' this is the path to the file to be downloaded
strFileToDownload = Request.QueryString("file")

 ' right now there are no checks on the path...
 ' anyone could download anything on our server
 ' but since this is a test, I don't care...

 ' pass the path to the function that will read the
 ' file
strFileContents = FileRead( strFileToDownload )


 ' prepare to write everything...
With Response

	 ' add the header with the download file's name
	.AddHeader "Content-Disposition", "filename=" & strFileToDownload

	 ' change the content type from text/html to
	 ' the downloadable one...
	.ContentType = "application/octet-stream"

	 ' if you wanted to write something else, you could do it here as well:
	.Write "Thanks for downloading this file!" & vbCrLf & vbCrLf

	 ' write the file's contents which was
	 ' passed from the function above.
	.Write strFileContents
End With

 ' done!
%>

Believe it or not, we are done. As I mentioned in the source code, this system will allow anyone to download anything on any drive of your server, assuming the FSO has permissions to roam freely around the server, which is usually does by default... So before you actually use this system, you should decide on a download area and restrict access to any other directory to prevent unauthorized downloading of files...

Download

http://downloads.aspemporium.com/ASPdownload.zip