구글와이드(336x280)_상단 2개


(영문)Browser-based File Uploading Under the Microscope ASP, ASP.NET

Browser-based File Uploading Under the Microscope
By Peter Persits
Introduction
Browser-based file uploading is a great way to transfer arbitrary files from a client machine to the Web server. The only software that the user needs is an RFC1867-enabled browser such as Netscape 3.0+, IE 4.0+, or IE 3.0 with an upload add-on. Uploading is performed via an HTML form with the attribute ENCTYPE="multipart/form-data". This form must also contain one or more <INPUT TYPE=FILE> items with which the user specifies local files to be uploaded.
The ENCTYPE="multipart/form-data" attribute instructs the browser to send the form data to the server in a multi-part format where each item on the form is accompanied by a number of MIME headers and separated from the rest of the items by delimiters. This MIME data must be parsed by a server-side process to extract individual items. Although theoretically achievable with pure ASP script, this task should really be delegated to a high-performance compiled component such as AspUpload from Persits Software, Inc. (http://www.persits.com).
Using the Request.BinaryRead Method to Examine POST Data
Let's start our exploration of file uploading by examining a posting sent by a regular HTML POST form without an ENCTYPE attribute. We will do so with the help of the Request.BinaryRead method. This method gives us access to the raw (unparsed) data sent to the server by a form. This method takes one parameter which specifies the number of bytes to read. We want to read the entire block of data sent, so will simply pass a value returned by another method of the Request object, TotalBytes.
The Request.BinaryRead method is a rare guest in ASP scripts, simply because Request.Form and Request.QueryString are much more convenient to use. Besides, this method packs the result data in a Variant-wrapped safe array of bytes, which is a tough nut to crack for a scripting language designed to work only with Variants and safe arrays of Variants. But when it comes to file uploading, BinaryRead becomes absolutely invaluable.
The following HTML form is quite trivial and does not have an ENCTYPE attribute:
 <HTML>
<FORM METHOD=POST ACTION=Script.asp>
<INPUT TYPE=TEXT NAME=Item1>
<INPUT TYPE=HIDDEN NAME=Item2 VALUE=Value2>
<INPUT TYPE=SUBMIT>
</FORM>
</HTML> 

This form invokes the following simple script:
 <HTML>
<BODY>
<%
n = Request.TotalBytes
data = Request.BinaryRead(n)
For i = 1 to n
Response.Write MidB( data, i, 1 )
Next
%>
</BODY>
</HTML> 

Note
We use the MidB function to access individual bytes of the data array returned by BinaryRead.
Once the form is submitted, the script will produce something like this:
 Item1=test+test&Item2=Value2 

You certainly recognize the standard URL encoding.
Now let's add the ENCTYPE="multipart/form-data" attribute to our <FORM> tag and submit it again.
The output will look quite differently now:
 -----------------------------7ce9c39120306
Content-Disposition: form-data; name="Item1"

test test
-----------------------------7ce9c39120306
Content-Disposition: form-data; name="Item2"

Value2
-----------------------------7ce9c39120306-- 

There are two sections separated by a delimiter in this data block, each corresponding to an item on our form. Each section begins with the MIME header Content-Disposition.
If we attempt to access individual form items using the standard Request.Form collection, we will get absolutely nothing. The Form collection is now totally useless since it can only work with data in the standard URL encoding format.
We will conclude our little research by adding an <INPUT TYPE=FILE NAME=FileItem> item to our form. This item shows up in the browser as an input box with a "Browse" button sitting next to it.
Note
If your browser does not show the "Browse" button it most probably means that the browser does not support file uploading.
Clicking the Browse button invokes a "Choose File" dialog which lets us pick a file for uploading. For this example, I picked a small GIF file and here is the output that I got:


-----------------------------7ce25134120306
Content-Disposition: form-data; name="FileItem"; filename="D:\HomePage\New\bg.gif"
Content-Type: image/gif

GIF89a? ?薛?}}^^^┲,?  
-----------------------------7ce25134120306
Content-Disposition: form-data; name="Item1"


-----------------------------7ce25134120306
Content-Disposition: form-data; name="Item2"

Value2
-----------------------------7ce25134120306-- 

You can see that the binary file bg.gif turns out to be embedded in the first section of the multi-part data block. Unlike Base64 email attachments, the file is not encoded in any way.
Notice that the Content-Disposition header for the file section has one more attribute, filename, which is set to the original full path of the file being transported. Also, the file section has one more MIME header, Content-Type.
Uploading Files with AspUpload
You could, of course, write some ASP script that would parse the data array returned by Request.BinaryRead, extract individual file, and save them on hard drive. Fortunately, there are several inexpensive uploading components out there that will save you the trouble.
AspUpload from Persits Software (http://www.persits.com) will do the job in just two lines of ASP code. This component handles multiple uploaded files as well as non-file items.
For our first example we will use the following HTML form that allows us to upload up to three files simultaneously:
 <HTML> 
<BODY BGCOLOR="#FFFFFF"> 
<FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="UploadScript1.asp"> 
<INPUT TYPE=FILE SIZE=60 NAME="FILE1"><BR> 
<INPUT TYPE=FILE SIZE=60 NAME="FILE2"><BR> 
<INPUT TYPE=FILE SIZE=60 NAME="FILE3"><BR> 
<INPUT TYPE=SUBMIT VALUE="Upload!">
</FORM>
</BODY> 
</HTML> 

The upload script UploadScript1.asp looks like this:
 <HTML> 
<BODY> 
<% 
Set Upload = Server.CreateObject("Persits.Upload.1") 
Count = Upload.Save("c:\upload")
%> 
<% = Count %> files uploaded. 
</BODY> 
</HTML> 

The first line of the script simply creates an instance of the AspUpload component. The second line calls the Save method and passes the destination directory as a parameter. The Save method internally calls Request.BinaryRead, parses the data array returned, extracts the files contained in the posting, and saves them in the specified destination directory under their original names. This method returns the number of successfully uploaded files.
You may use any or all input boxes on the form. AspUpload is smart enough to figure out which boxes are being used and which are not.
Accessing Individual Files and Non-File Form Items
Our next form will contain both file and regular text items:
 <HTML> 
<BODY BGCOLOR="#FFFFFF"> 
<FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="UploadScript2.asp"> 
File 1:</TD><TD><INPUT TYPE=FILE NAME="FILE1"> 
Description 1:<INPUT TYPE=TEXT NAME="DESCR1"><BR> 

File 2:<INPUT TYPE=FILE NAME="FILE2"> 
Description 2:<INPUT TYPE=TEXT NAME="DESCR2"><BR> 
<INPUT TYPE=SUBMIT VALUE="Upload!">
</FORM>
</BODY> 
</HTML> 

Here is the corresponding upload script UploadScript2.asp:
 <HTML> 
<BODY> 
<% 
Set Upload = Server.CreateObject("Persits.Upload.1") 
Upload.Save "c:\upload"
%> 
Files:<BR> 
<% 
For Each File in Upload.Files 
Response.Write File.Name & "=" & File.Path & " (" & File.Size & ")<BR>"
Next
%> 
<P> 
Other items:<BR> 
<% 
For Each Item in Upload.Form 
Response.Write Item.Name & "=" & Item.Value & "<BR>"
Next
%> 
</BODY> 
</HTML> 

As I mentioned before, we can no longer use the Request.Form collection to access individual items on a form with the ENCTYPE attribute. But not to worry: AspUpload provides a Form collection of its own, which is similar to Request.Form. We can access individual items in this collection using integer indexes or string names, e.g.
 Response.Write Upload.Form(1) 

or
 Response.Write Upload.Form("DESCR1") 

We can also scroll through the items in the collection using the For-Each statement as shown in the script above.
The Upload.Form collection only contains non-file form items, i.e. items other than <INPUT TYPE=FILE>. AspUpload provides one more collection, Upload.Files, to represent the files coming from <INPUT TYPE=FILE> items of the form. Each item in this collection is an object of the type UploadedFile. This object provides a lot of methods and properties which enable you to query and manipulate each uploaded file.
Example 2 will produce something like this:
 Files: 
FILE1=c:\upload\File1.xls (108544) 
FILE2=c:\upload\File2.zip (211687) 

Other items: 
DESCR1=bla bla 
DESCR2=test test  

Notice that we have obtained the files' destination paths and sizes via the Path and Size properties of the UploadedFile object, respectively.
It is important to remember that you cannot use the Upload.Form or Upload.Files collections until the Save method is called. For example, if you want to enable your users to specify the destination directory in the upload form, you may be tempted to write the following code:
 ' Incorrect
n = Upload.Save(Upload.Form("Path")) 

This will not work because the Form collection will not be populated until the Save method is called. The correct way of doing this would be to upload files to a fixed directory and then move or copy them to the user-specified directory:
 ' Correct
n = Upload.Save "c:\upload"
For Each File in Upload.Files
        File.Copy Upload.Form("Path") & "\" & File.ExtractFileName
Next 

Saving Uploaded Files in Database as Blobs
Many database management systems like MS Access or SQL Server can store arbitrary files as "binary large objects" (BLOBs). An MS Access table can store binary files in data fields of the type OLE Object. In SQL Server, the corresponding data type is called BINARY. The stored files can later be retrieved for downloading or displaying using ADO.
AspUpload allows you to store an uploaded file in a database table in just one line of ASP code.
The HTML file for example 3 is almost identical to that of example 1 (except for the ACTION attribute):
 <HTML> 
<BODY BGCOLOR="#FFFFFF"> 
<FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="UploadScript3.asp"> 
<INPUT TYPE=FILE SIZE=60 NAME="FILE1"><BR> 
<INPUT TYPE=FILE SIZE=60 NAME="FILE2"><BR> 
<INPUT TYPE=FILE SIZE=60 NAME="FILE3"><BR> 
<INPUT TYPE=SUBMIT VALUE="Upload!">
</FORM>
</BODY> 
</HTML> 

Here is the script UploadScript3.asp:
 <HTML> 
<BODY> 
<% 
Set Upload = Server.CreateObject("Persits.Upload.1") 
Upload.Save "c:\upload" 
On Error Resume Next 
For Each File in Upload.Files 
File.ToDatabase "DSN=data;UID=sa;PWD=xxx;",_
        "insert into Blobs(id, Path, BigBlob)" &_
        "values(12, '" & File.Path & "', ?)"
if Err <> 0 Then 
Response.Write "Error saving the file: " & Err.Description
Else 
File.Delete 
Response.Write "Success!"
End If
Next
%> 
</BODY> 
</HTML> 

The workhorse method in this example is File.ToDatabase which accepts two arguments. The first argument is an ODBC connection string in the format
 "DSN=<datasource name>;UID=<userid>;PWD=<password>;<other optional attributes>" 

The second argument is an SQL INSERT or UPDATE statement which must contain a question mark (?) representing the actual file being saved in the database. In the example above we insert three values in the table Blobs: 12 in the field "id", the file path in the field "Path", and the actual uploaded file in the field "BigBlob".
Notice that this example uses the On Error Resume Next statement to catch exceptions that may be thrown by AspUpload's methods in case of an error.
It is not uncommon to store GIF and JPEG images in a database table. To retrieve an image from the table and display it on an HTML page, you don't need to use any third-party component. ADO will do the job for you.
Put a regular <IMG> tag on your HTML page with the SRC attribute pointing to an ASP script, e.g.
 <IMG SRC="GetImage.asp?id=4"> 

The GetImage.asp script may look like this:
 <%
Set db = Server.CreateObject("ADODB.Connection")
db.Open "data"
Set rs =db.Execute("SELECT BigBlob FROM Blobs where id = " & Request("id") )
Response.ContentType = "image/jpeg" '(or "image/gif")
Response.BinaryWrite rs("BigBlob")
%> 

More Info on AspUpload
AspUpload provides tons of features not covered in this article that you may find very useful, such as unique filename generation to avoid collisions with existing files in the upload directory. Or you can configure the component to truncate or reject files that exceed certain size. And finally you can find features no other uploading component on the market offers, such as NT Access Control List (ACL) manipulation or remote ActiveX DLL registration.
For more information and to download your free trial copy of AspUpload, visit the Persits Software web site at http://www.persits.com/aspupload.html. You will also find a live demo application that allows you to actually upload files to our server. If you have questions don't hesitate to write to us at info@persits.com.

null



바보들의 영문법 카페(클릭!!)

오늘의 메모....

시사평론-정론직필 다음 카페
http://cafe.daum.net/sisa-1

바보들의 영문법 다음 카페
http://cafe.daum.net/babo-edu/

티스토리 내 블로그
http://earthly.tistory.com/

내 블로그에 있는 모든 글들과 자료에 대한 펌과 링크는 무제한 허용됩니다.
(단, 내 블로그에 덧글쓰기가 차단된 자들에게는 펌, 트랙백, 핑백 등이 일체 허용되지 않음.)

그리고 내 블로그 최근글 목록을 제목별로 보시려면....
바로 아래에 있는 이전글 목록의 최근달을 클릭하시면 됩니다.
그러면 제목을 보고 편하게 글을 골라 보실 수 있습니다.

그리고 내 블로그내 글을 검색하시려면 아래 검색버튼을 이용하시면 됩니다.


가가챗창

flag_Visitors

free counters