ASP (Active Server Page) is a product of Microsoft. Because it is easy to program and can quickly develop dynamic websites with powerful functions, many websites (especially intranet/extranet intranets) now adopt the NT+IIS+ASP model, making ASP the current The more popular scripting language for website development. In WEB services, file upload service is a very common function, but PWS under WIN9X does not provide related components; IIS under NT provides a Post Acceptor component, but it is not easy to use because it checks the user's WWW access rights; you can also download related components from the Internet, but most of these are commercial components, and the ones used for downloading are trial versions. During the use time or There are restrictions on functionality. Since ASP can call standard OLE/COM components, we can use advanced programming tools such as VB/VC/DELPHI to customize our own ASP file upload components according to our own requirements to meet our own application system requirements.
The following will discuss the principle and specific implementation process of using DELPHI to develop file upload components for ASP.
1. Implementation principle of file upload
Web-based data upload must comply with the RFC1867 standard, and uploaded file data is no exception. For example, use the following HTML page file (delphiup.htm) to select the upload file:
<!-- DelphiUp.htm: File upload interface -->
<html><head><title>File upload</title></head><body>
Implement file upload using file upload component written in DELPHI
<form NAME="UploadForm" ACTION="delphiup.asp" METHOD="POST" ENCTYPE="multipart/form-data">
<p>Save file as: <input TYPE=text NAME="SaveAs">
<p>Please select the file to upload: <input TYPE=file NAME="FileData">
<input type="submit" name="b1" value="Confirm upload"> </p>
</form>
</body></html>
When the client selects a file (such as Test.TXT, whose content is "Here is the content of a file for uploading.") and press
After the "Confirm Upload" button submits the data, the data received by the server-side program will have the following form:
--------------------------7cf1d6c47c#13#10
Content-Disposition: form-data; name="SaveAs"#13#10#13#10
NewFileName#13#10
--------------------------7cf1d6c47c#13#10
Content-Disposition: form-data; name="FileData"; filename="D: est.txt"
Content-Type: text/plain#13#10#13#10
Here is the content of a file for upload. #13#10
--------------------------7cf1d6c47c#13#10
Content-Disposition: form-data; name="b1"#13#10#13#10
Confirm upload#13#10
--------------------------7cf1d6c47c--
Among them, "--------------------------------7cf1d6c47c" is the delimiter used to separate each field in the form (Form);
#13#10 is the DELPHI representation of carriage return and line feed characters. We can think of it this way, the information description of each form field starts with a delimiter plus a pair of carriage returns and line feeds #13#10; the form domain name starts with "name="" and ends with """; the form field The value starts with two pairs of carriage return and line feed characters #13#10#13#10, and ends with a pair of carriage return and line feed characters #13#10# plus a delimiter; the file name starts with "filename="" and ends with """ for the end. With these flags, we can get the name and value of the form field and the name of the file to be uploaded, so that the file data can be read and stored.
2. Implementation process of file upload
After understanding the data format mentioned above, it is no longer difficult for us to write a file upload component ourselves.
(1) Start a project to create an ASP component
If you are not familiar with the steps of using DELPHI to develop OLE Automation Server, please refer to an article "Using DELPHI to develop OLE Automation Server for ASP" in "Electronics and Computers", Issue 06, 1999.
Here we only briefly introduce the steps.
1. Create an ActiveX Library project
In DELPHI, select the menu File="New..., select "ActiveX Library" in the ActiveX tab of the "New Item" dialog box, and DELPHI will automatically create a DLL project PRoject1.
2. Create Automation components
In DELPHI, select the menu File="New..., select "Automation Object" in the ActiveX tab of the "New Item" dialog box; then enter the Class Name (such as "UploadFile") in the "Automation Object Wizard" dialog box ,Instancing select "Multiple Instance". After clicking "OK", DELPHI will automatically create a TLB (Type Library) file Project1_TLB.PAS and a PAS (Unit) file Unit1.PAS. In the Type Library design window, rename Project1 to MyUpload, then the OLE registration code of the file upload component is "MyUpload.UploadFile".
3. Introduce ASP type library
In order to use the five built-in objects of ASP (Request, Response, Server, application, session), the ASP type library needs to be introduced. We mainly use the Request object to read the data passed from the client to the server.
Select "Import Type Library" in the Project menu, and select "Microsoft Active Server Pages Object Library(Version)" in the "Type Libraries" list of the "Import Type Library" dialog box. 2.0)" (If this option is not available, please make sure IIS3 or above or PWS4 or above is installed on your computer and ASP.DLL has been registered correctly), D ELPHI will automatically create a TLB file ASPTypeLibrary_TLB.PAS, which contains the ASP object type declaration we need.
4. Define the OnStartPage and OnEndPage processes
When using Server.CreateObject to create an OLE object instance on an ASP page, the WEB server will call its method OnStartPage and pass the ASP application environment information to the object. , we can obtain the client information during this process; when an OLE object instance is released in the ASP page, the WEB server will call its method OnEndPage, and we can perform end operations such as releasing memory during this process. In our component, we need to use its OnStartPage method.
The OnStartPage method should be defined in Unit1.PAS. The function prototype of OnStartPage is:
procedure OnStartPage(AScriptingContext: IUnknown);
The parameter AScriptingContext is an IScriptingContext type variable, including five attributes (Request, Response, Server, Application, Session) corresponding to five built-in objects of the same name in ASP.
We need to add the method OnStartPage to IUploadFile in the TLB definition window (View="Type Library), and its Declaration statement is "procedure OnStartPage(AScriptingContext: IUnknown);".
(2) Extract data uploaded by the client
This work can be done in the OnStartPage process.
Using the property TotalBytes (request information content length) and method BinaryRead in the property Request (type IRequest) of AScriptingContext, the request information data uploaded by the client can be read into a Byte type array, and then the data format defined by the RFC1867 standard to analyze and extract data.
1. First define several private variables of TUploadFile
Add a reference to ASPTypeLibrary_TLB.PAS (Uses) in the unit file UP01.PAS (saved by Unit1.PAS),
then join
private
FContentLength: LongInt; //Request information content length
FContentData: Variant;//Content data, stores the request information content in the form of an array
FFileName, //The name of the file to be uploaded
FDelimeter: string; //Form field delimiter
FScriptingContext: IScriptingContext;//ASP processes context content
FFileDataStart, //Start position of file data
FFileDataEnd: LongInt; //End position of file data
2. Extract the request information data uploaded by the client
//In the OnStartPage event, obtain the ASP context information, request information content, form field delimiters, and file data
procedure TUploadFile.OnStartPage(AScriptingContext: IUnknown);
var
ARequest: IRequest; //WWW request object
AOleVariant: OleVariant; //Record the length of request information content
intDelimterLength: integer;//Delimiter length
longIndex,ALongInt,longPos : LongInt;
ContentData: AnsiString;//String representation of request information content
strTemp: string;
FindEndOfFileData: boolean;//Whether the end position of the file data is found
begin
//Extract the request information data uploaded by the client
FScriptingContext := AScriptingContext as IScriptingContext;//Get ASP context information
ARequest := FScriptingContext.Request;//Get WWW request information
FContentLength := ARequest.TotalBytes;//Request information content length
//Create a dynamic array to store the request information content in the form of an array
FContentData := VarArrayCreate( [0,FContentLength], varByte );
//Store the request information content into the array
AOleVariant := FContentLength;
FContentData := ARequest.BinaryRead(AOleVariant);//Read the request information content
//Convert the request information content into a string for easy positioning
ContentData := ';
for longIndex := 0 to FContentLength - 1 do
begin
ContentData := ContentData + chr( Byte( FContentData[ longIndex ] ));
if FContentData[ longIndex ] = 0 then break;//0 indicates the end of the content
end;
3. Get delimiter and upload file name
//Get the delimiter of the form field
longPos := pos( #13#10,ContentData );//The position of the carriage return and line feed character
FDelimeter := Copy( ContentData,1,longPos-1);//The content before this position is the delimiter
//Get the file name with source path. In the request information content, the file name starts with
//Storage in the form of filename="path/filename"
strTemp := 'filename="';//The file name is after "filename=""
longPos := pos( strTemp, ContentData );//Get the "filename="" position
if longPos <= 0 then
begin
FFileName := ';
FFileDataStart := -1;
FFileDataEnd := -2;
exit;
end;
//Get the content before the next double quote """, that is, the file name with the source path
longPos := longPos + length( strTemp );
strTemp := ';
for longIndex := longPos to FContentLength - 1 do
if ContentData[ longIndex ] <> '"' then
strTemp := strTemp + ContentData[ longIndex ]
else break;
FFileName := strTemp;
4. Obtain the start and end positions of the file data in the request information content
//The starting position of the file data is after the first #13#10#13#10 after the file name
delete( ContentData, 1, longIndex );
strTemp := #13#10#13#10;
FFileDataStart := longIndex + pos(strTemp, ContentData) + length(strTemp) - 1;
//The end position of the file data is before the next #13#10 and the delimiter
//Since the file data may contain illegal characters, the string positioning function POS cannot be used anymore.
//Find the position of the next delimiter
FFileDataEnd := FFileDataStart;
intDelimterLength := length( FDelimeter );
FindEndOfFileData := false;
while FFileDataEnd <= FContentLength - intDelimterLength do
begin
FindEndOfFileData := true;
for ALongInt := 0 to intDelimterLength - 1 do
if Byte( FDelimeter[ ALongInt + 1 ] ) <>
FContentData[FFileDataEnd + ALongInt] then
begin
FindEndOfFileData := false;
break;
end;
if FindEndOfFileData then break;
FFileDataEnd := FFileDataEnd + 1;
end;
if not FindEndOfFileData then FFileDataEnd := FFileDataStart - 1//No delimiter found
else FFileDataEnd := FFileDataEnd - 3;//Delimiter, skip forward #13#10
end;
(3) Transmit information to ASP program
After performing the operation (2), our upload component can pass data to the ASP program according to its requirements. The data currently available include: client source file name (FFileName, including path), file size (FFileDataEnd-FFileDataStart+1).
First, the following two methods GetFileName and GetFileSize should be declared in the TLB design window.
1. Return the client source file name (including path)
//Return client source file name (including path)
function TUploadFile.GetFileName: OleVariant;
begin
result := FFileName;//Client source file name (including path)
end;
2. Return file size
//Return file size (Bytes)
function TUploadFile.GetFileSize: OleVariant;
begin
result := FFileDataEnd - FFileDataStart + 1;
end;
(4) Save files
After performing the operation (2), our upload component can save the file according to the requirements of the ASP program. First it should be in
The following two methods, SaveFileAs and SaveFile, are declared in the TLB design window.
1. Save the file according to the specified file name
//Save the file according to the specified file name. The parameter FileName is the specified file name. The return value True indicates that the file is saved successfully.
function TUploadFile.SaveFileAs(FileName: OleVariant): OleVariant;
var
longIndex : LongInt;
AFile: file of byte;//Save the file in binary form
byteData : Byte;
begin
result := true;
try
assign(AFile, FileName);
rewrite(AFile);
for longIndex := FFileDataStart to FFileDataEnd do
begin
byteData := Byte( FContentData[ longIndex ] );
Write(AFile, byteData);
end;
CloseFile( AFile );
except
result := false;
end;
end;
2. Save the file with the default file name
//Save the file according to the default file name, and save the file with the same name in the directory where the calling page is located
function TUploadFile.SaveFile: OleVariant;
var
CurrentFilePath : string;
begin
//Get the directory where the calling page is located
CurrentFilePath := FScriptingContext.Request.ServerVariables['PATH_TRANSLATED'];
CurrentFilePath := ExtractFilePath( CurrentFilePath );
//save file
result := SaveFileAs( CurrentFilePath + ExtractFileName( FFileName ));
end;
3. Application examples of upload components
In our example, DelphiUp.HTM is the file upload interface, and DelphiUp.ASP is used to perform file upload operations.
The code of DelphiUp.ASP is as follows:
<!--DelphiUp.ASP: File upload processing page-->
<html><head><title>File upload</title></head><body>
<% dim Upload, FileName
set Upload = Server.CreateObject("MyUpload.UploadFile")
FileName = Upload.GetFileName
Response.Write "<br>Saving file ""&FileName&""..."
if Upload.SaveFile then
Response.Write "<br>The file ""&FileName&"" was uploaded successfully."
Response.Write "<br>The file size is "&Upload.GetFileSize&" bytes."
else
Response.Write "<br>File ""&FileName&"" failed to upload."
end if
set Upload=nothing %>
</body></html>
4. Some explanations
1. The size of the DLL file compiled from the source code automatically generated by DELPHI is 215K, which can be found in
In the Interface section of ASPTypeLibrary_TLB.PAS, delete all units in Uses except ActiveX.
By deleting all units in Uses in MyUpload_TLB.PAS, the size of the generated DLL file can be reduced to 61K.
2. The above method is also applicable to CGI programs, but the TWebRequest object must be used.
The above program was debugged and passed under PWIN98+Delphi3.0+PWS4.0.