Develop ASP upload components with Delphi 6

zhaozj2021-02-16  63

File upload is the function that is often used in web development, but the ASP itself and built-in components do not support file upload functions. Some third party components circulated online can solve this problem, but most of them are charged, let alone Open Source. This article will detail the principle upload of the web file, and how the reader will develop an ASP upload component with Delphi6.

1 HTML file analysis First let's look at an HTML file source code, the file name is Test.htm, the function is to provide the user uploaded interface:


This file contains a Form called Mainform, and some input domains written. Note that this form and a general form have two different places: First, it has a type = file domain, no value. When you open this file with your browser, this domain will behave as a file input box with a "Browse" word on the right, and the user can select the file on the local hard disk. Second, Form has a special attribute: encType = "Multipart / Form-Data". This property tells the browser to upload binary and make the corresponding encoding. What kind of form information will this code produce? Let's take a look at Test.asp, which is the source code for the ASP file of the form, it is very simple:

<% Formsize = Request.TotalBytes' Length FormData = Request.binaryRead (Formsize) 'Read Form Original Information Response.binaryWrite Formata' Return Form Original Information%>

As the reader understands in the comment, the function of this code is to return the original information of the form. Let's take a look at its operation. Place the two files in a web directory and access Test.htm. In the File Input box, select a file (I chose a JPG picture, but the biggest should not be too big). Submit, then you can see such a pile of seven-eight-piece information:

---------------------------- 7D2227629012E Content-disposition: form-data; name = "mefile"; filename = "C: / Documents and settings / aaa / my documents / my pictures / zzjh.jpg "Content-Type: image / pjpeg (Author Note: The following is garbled) ------------------- ---------- 7D2227629012E Content-disposition: form-data; name = "a1" fdsaf ------------------------- ---- 7D2227629012E Content-disposition: form-data; name = "a2" fdsaf ---------------------------- 7D2227629012E Content -Disposition: form-data; name = "a3" fdsaf ----------------------------- 7D2227629012E Content-Disposition: Form-Data Name = "a4" fsdfsdsaF ---------------------------- 7D2227629012E Content-Disposition: form-data; name = "a5" This is this ----------------------------- 7D2227629012E Content-disposition: form-data; name = "a6" fdsaf --- -------------------------- 7D2227629012E Content-Disposition: form-data; name = "ok" OK --------- -------------------- 7D2227629012E - this is the original information encoded with "multipart / form-data". One of the sections appeared to be garbled, it is the code of the JPG image. (The actual JPG picture coding may be much longer than this, depending on the file size. For the sake of the text, the author only retains a small part.) Analyze the format of this information:

---------------------------- 7D2227629012E This is a separator between individual domains. Content-Disposition: Form-Data; Description This is the domain in the form. Name = "mefile"; the name of the domain. FileName = "c: / documents and settings / aaa / my documents / my pictures / zzjh.jpg" Upload the name on the local hard drive. Content-type: image / pjpeg file type. Behind the data of the file itself.

Information in other domains can also be pushed in this type. As is well known, in ASP, use the Request object, you can access the various domains of the user submitting the form. Because the Request object parses the original form information, extract the value of each domain in the form. However, REQUEST does not resolve form information in "Multipart / Form-Data" format. This is the reason why ASP cannot directly support file upload. Readers can try, in Test.asp, with the format such as Request ("MEFILE"), it is not possible to read the correct information. The problem of the problem has been found, the idea of ​​solving is also very simple: develop a COM component with Delphi, accept this original form information, extract each domain one by one, return to the ASP file. That is, the function of completing the Request object is not completed. 2 Develop components with Delphi

Delphi6 provides excellent support for developing ASP components, greatly simplifies our development process. Start Delphi 6, select File-New-Other-ActiveX-ActiveX Library, this is created an ActiveX library. Return this library to myObj and store. Select File-New-Other-ActiveX-Active Server Object to fill in UPFile in CoclassName, determine. At this time, a dialog of Myobj_TLB will be jumped out, which is the function of Delphi's unique to edit the COM interface. The reader who develops COM in Delphi should be more familiar. Add 5 attributes and one way to IUPFILE's Interface in MyObj. If you don't know how to do it, see the relevant part of the Delphi reference book. Press F12 to see the generated corresponding myobj_tlb.pas file, where the Iupfile interface should look like:

Iupfile = interface (IDispatch) [ '{5C40D0EB-5A22-4A1E-8808-62207AE04B51}'] procedure OnStartPage (const AScriptingContext: IUnknown); safecall; procedure OnEndPage; safecall; function Get_Form (Formname: OleVariant): OleVariant; safecall; function Get_FileName: OleVariant; safecall; function Get_FileSize: Integer; safecall; procedure FileSaveAs (FileName: OleVariant); safecall; function Get_FileData: OleVariant; safecall; function Get_FileType: OleVariant; safecall; property Form [Formname: OleVariant]: OleVariant read Get_Form; property Filename: Olevariant Read Get_FileName; Property FileSize: Integer Read_FileSize; Property FileData: Olevariant Read_FileData; Property FileType: Olevariant Read_FileTy;

The onStartPage method and oneundPage method are Delphi generated by default, and others are manually added. Switch to Unit1.pas (also automatically generated by Delphi), renameding an UPFILE.PAS store. It can be seen that there is a declaration of a Tupfile class, which is inherited from the TaspObject class and the Iupfile interface. Delphi 6 has automatically generated corresponding code. The next task is to implement this interface. In addition to completing the properties and methods in the Iupfile interface, you also need to add something to complete our task. The final declaration of Tupfile class as follows: Tupfile = class (TASPObject, Iupfile) publicprotectedprocedure OnEndPage; safecall; // page to start the procedure OnStartPage (const AScriptingContext: IUnknown); safecall; // page end procedure FileSaveAs (Filename: OleVariant); safecall; // save the file function Get_Form (Formname: OleVariant): OleVariant; safecall; // function Get_FileName: OleVariant; safecall; function Get_FileSize: Integer; safecall; function Get_FileData: OleVariant; safecall; function Get_FileType: OleVariant; safecall; privateFContentData: string; FFileData, FFileType: String; FFormInfo: TstringList; Function INSTR (STR1, STR2: STRING; StartPos: Integer): Integer; Procedure AnalyformData (Content: string);

Let's take a specific implementation of these members.

procedure Tupfile.OnStartPage (const AScriptingContext: IUnknown); varAOleVariant: OleVariant; tmpvar: OleVariant; contentlength: integer; i, DeliCount, pos1, pos2, lastpos: integer; FDelimeter: string; begininherited OnStartPage (AScriptingContext); FFormInfo: = TStringList. CREATE

contentlength: = Request.TotalBytes; AOleVariant: = contentlength; tmpvar: = Request.BinaryRead (AOleVariant); for i: = 1 to contentlength -1 dobeginFContentData: = FContentData chr (byte (tmpvar [i])); end;

POS1: = POS (# 13 # 10, fcontentdata); fdelimeter: = Copy (fcontentData, 1, POS1 1); DELICOUNT: = Length (fdelimeter); LastPos: = 1;

POS1: = 0; While Pos2> = POS1 DOBEGINPOS1: = INSTR (FDELIMETER, FCONTENTDATA, LASTPOS); if Pos1 = 0 Then Break; POS1: = POS1 DELICOUNT; POS2: = INSTR (FDELIMETER, FCONTENTDATA, POS1) -1; AnalyieldData, POS1, POS2-POS1-1); LastPos: = POS2; END; END; before, the onStartPage method is automatically generated by Delphi and occurs when loading the page. In this method, we have completed some initialized tasks: read the original data of the form, parse the domain in the form, and store the corresponding properties for the call. Since Delphi has made a good package in the ASP, even in the Delphi environment, they can be easily called, just like the ASP, such as request.totalbytes. First read the original form data into a TMPVAR of an OLEVIARIANS type, then convert it to the String format in Delphi, and store it in FcontentData. Next, the content and length of the separator is parsed by finding a newline character. Then, in a loop, use the AnalyformData member function one by one to each domain. Initialization work is done like this.

Realize the AnalyformData function again:

Procedure Tupfile.AnalyformData (Content: String); Varpos1, Pos2: Integer; FormName, FormValue: String; IsFile: Boolean; Beginisfile: = FALSE; POS1: = INSTR ('Name = ", Content, 1) 6; POS2 : = INSTR ('", Content, POS1); FormName: = COPY (Content, POS1, POS2-POS1);

// Check if the file POS1: = INSTR ('filename = ", content, POS2 1); if Pos1 <> 0 thenbeginisfile: = true; POS1: = POS1 10; POS2: = INSTR ('", Content , POS1); FFileName: = COPY (Content, POS1, POS2-POS1);

POS1: = INSTR (# 13 # 10 # 13 # 10, Content, POS2 1) 4; FormValue: = COPY (Content, POS1, Length (Content) -pos1);

If isfile kilinffiledata: = formvalue; // Find file type information POS2: = INSTR ('content-type:', content, pos2 1); if Pos2 <> 0 thenbeginpos2: = POS2 14; ffilety: = copy (Content , POS2, POS1-4-POS2); end; endelsebeginfforminfo.add (FormName '=' FormValue); End; end;

As expressed in the comment, AnalyformData extracts the domain in the original data. If the domain is the file type, put file type and file data in FFileType and FFileData, respectively. If you are other types, add names and values ​​in a TStrINGList type FFormInfo. In FFormInfo, you have maintained all domains of all domains outside the file, stored in the format of "Name = Value". Function Tupfile.get_form (FormName: Olevariant): Olevariant; beginResult: = fforminfo.values ​​[form "; end; this function returns the value of the field. It is only necessary to simply call the FFormInfo VALUES method, you can get the corresponding value. This is implemented inside the TSTRINGLIST class.

Function tupfile.get_filename: olevariant; beginResult: = extractFileName (ffilename);

Function tupfile.get_filesize: integer; beginResult: = Length (ffiledata);

Function tupfile.get_filedata: olevariant; vari: integer; beginResult: = varagecreate ([0, length (ffiledata)], varbyte; for i: = 0 to length (ffiledata) -1 dobeginResult [i]: = byte (ffiledata i 1]); end;

These three functions returned to the name, size, and data of the file, respectively. It should be noted that when returning file data, the corresponding conversion must be performed, and the String type in Delphi is converted to the Olevariant type. procedure Tupfile.FileSaveAs (Filename: OleVariant); varfsout: TFileStream; beginfsout: = TFileStream.Create (Filename, fmcreate); tryfsout.Write (Byte (FFileData [1]), Length (FFileData)) finallyfsout.Free; end;

END;

This method saves files to disk on the server.

Compile this Project, get a Myobj.dll file. Development work is done.

3 Using the ASP uploading assembly to enter "Regsvr32 Myobj.dll" in the command line. Pop up a dialog and tell you that the component has been registered. If you can't find the regsvr32.exe file, it is in Windows / System32 or WinNT / System32 directory. Modify the test.asp file mentioned in this article as follows:

<% 'Establishing Object Set UpFile = Server.createObject ("Myobj.upfile")

'Get form object response.write upfile.form ("a1") & "
" Response.write Upfile.form ("A2") & "
" Response.write Upfile.form ("A3") & "
" Response.write Upfile.form ("A4") & "
" Response.write Upfile.form ("A5") & "
" Response.write Upfile.form ("A6") & "
" 'Get the Size RESPONSE.WRITE "file byte number:" & updile.filesize & "
"' Get file type response.write file type: "& upfile.filetype &"
"

'Get file names, save file upfile.filesaveas (server.mappath (") upfile.filename)

SET UPFILE = NOTHING%>

Access Test.htm again, submit the form. Now you can see the relevant return information, and find the uploaded files in the directory where Test.asp is located on the server. This component can only upload a single file, but according to the same principle, the function of uploading multiple files at a time is not difficult to implement. Interested readers can try themselves.

Zuo Lou 2002.6.20

转载请注明原文地址:https://www.9cbs.com/read-27473.html

New Post(0)