Develop ASP upload components with Delphi 6

zhaozj2021-02-08  292

Developing ASP Upload Components with Delphi 6 Detailed Left Light 2002.6.20 File Uploading is the functionality 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.

Source code and demo I have been released at the Personal Homepage http://www.wuseuang.net

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 upload interface:


This file contains a name Mainform's Form, 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 'LeadData = Request.binaryRead (Formsize)' Read the form Information Response.BinaryWrite Formdata 'Returns Form Original Information%> If 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: / docuuments 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 a form encoded with "multipart / form-data" mode Original information. One of the sections appeared to be garbled, it is the code of the JPG picture. Analyze this format of this information: ---------------------------- 7D2227629012E This is a separator between the various 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 Use the Delphi Development Components Delphi6 to provide excellent support for the development of ASP components, greatly simplifying 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, which is the function of Delphi's unique to edit the COM interface. The reader who develops COM with 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 can see the corresponding myobj_tlb.pas files generated, wherein the Iupfile interface should look like this: 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 Get_FileSize; property FileData: OleVariant read Get_FileData; property FileType: OleVariant read Get_FileType; END; where the onStartPage method and oneundPage method are Delphi By default, 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) public protected procedure 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; private FContentData : string; FFileData, FFileName, FFileType: string; FFormInfo: TStringList; function instr (str1, str2: string; startpos: integer): integer; procedure AnalyFormData (content: string); end; Let's analyze one by one the members of the Implementation.

procedure Tupfile.OnStartPage (const AScriptingContext: IUnknown); var AOleVariant: OleVariant; tmpvar: OleVariant; contentlength: integer; i, DeliCount, pos1, pos2, lastpos: integer; FDelimeter: string; begin inherited OnStartPage (AScriptingContext); FFormInfo: = TStringList.Create; contentlength: = Request.TotalBytes; AOleVariant: = contentlength; tmpvar: = Request.BinaryRead (AOleVariant); for i: = 1 to contentlength -1 do begin FContentData: = 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 Do Begin Pos1: = INSTR (FDELIMETER, FCONTENTDATA, LASTPOS); if Pos1 = 0 Then Break; POS1: = POS1 DELICOUNT; POS2: = INSTR (FDELIMETER, FCONTENTDATA, POS1) -1; AnalyieldData (COPY (FconTentData, POS1, POS2-POS1-1); LastPos: = POS2; END; END; previously said, the onStartPage method is Delphi automatically generated, which occurs when the page is loaded. 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.

Realization of AnalyformData functions: Procedure Tupfile.AnalyformData (Content: String); VAR POS1, POS2: Inteder; FormName, FormValue: String; IsFile: Boolean; Begin IsFile: = 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 dam1: = POS1 10; POS2: = INSTR (' ", content, pos1); ffilename: = Copy (Content, POS1 POS2-POS1); END; POS1: = INSTR (# 13 # 10 # 13 # 10, Content, POS2 1) 4; FormValue: = COPY (Content, POS1, Length (Content) -pos1); if isfile THEN BEGIN FFILDATA: = FormValue; // Find file type information POS2: = INSTR ('content-type:', content, POS2 1); if Pos2 <> 0 THEN BEGIN POS2: = POS2 14; ffilety: = COPY (Content, POS2, POS1-4-POS2); END; END ELSE Begin Forminfo.add (FormName '=' FormValue); End; End; End; AnalogMData extracts the domain in the original data, as expressed in the comment. 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; Begin Result: = 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; begin Result: = ExtractFileName (FFileName); end; function Tupfile.Get_FileSize: Integer; begin Result: = length (FFileData); end; function Tupfile.Get_FileData: OleVariant; var i: integer; begin Result : = VararrayCreate ([0, Length)], Varbyte); for i: = 0 to length (ffiledata) -1 do begin result [i]: = byte (ffiledata [i 1]); end; 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); var fsout: TFileStream; i: integer; afile: file of byte; begin fsout: = TFileStream.Create (Filename, fmcreate); for i: = 1 to length (FFileData) do begin FSout.write (Byte (ffiledata [i]), 1) end; fsout.free; 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.

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

New Post(0)