ASP (Active Server Page) es un producto de Microsoft Debido a que es fácil de programar y puede desarrollar rápidamente sitios web dinámicos con funciones poderosas, muchos sitios web (especialmente intranets/extranets) ahora adoptan el modelo NT+IIS+ASP, lo que convierte a ASP en el modelo. actual El lenguaje de programación más popular para el desarrollo de sitios web. En los servicios WEB, el servicio de carga de archivos es una función muy común, pero PWS en WIN9X no proporciona componentes relacionados. IIS en NT proporciona una publicación; Componente aceptador, pero no es fácil de usar porque verifica los derechos de acceso a WWW del usuario; también puede descargar componentes relacionados de Internet, pero la mayoría de estos son componentes comerciales y los que se utilizan para descargar son versiones de prueba durante el uso. tiempo o Hay restricciones en la funcionalidad. Dado que ASP puede llamar a componentes OLE/COM estándar, podemos utilizar herramientas de programación avanzadas como VB/VC/DELPHI para personalizar nuestros propios componentes de carga de archivos ASP de acuerdo con nuestros propios requisitos para cumplir con los requisitos de nuestro propio sistema de aplicaciones.
A continuación se analizará el principio y el proceso de implementación específico del uso de DELPHI para desarrollar componentes de carga de archivos para ASP.
1. Principio de implementación de la carga de archivos.
La carga de datos basada en web debe cumplir con el estándar RFC1867 y los datos de archivos cargados no son una excepción. Por ejemplo, utilice el siguiente archivo de página HTML (delphiup.htm) para seleccionar el archivo de carga:
<!-- DelphiUp.htm: Interfaz de carga de archivos -->
<html><head><title>Carga de archivos</title></head><body>
Implementar la carga de archivos utilizando el componente de carga de archivos escrito en DELPHI
<formulario NOMBRE="UploadForm" ACTION="delphiup.asp" METHOD="POST" ENCTYPE="multipart/form-data">
<p>Guardar archivo como: <input TYPE=text NAME="Guardar como">
<p>Seleccione el archivo a cargar: <input TYPE=file NAME="FileData">
<input type="enviar" nombre="b1" valor="Confirmar carga"> </p>
</formulario>
</cuerpo></html>
Cuando el cliente selecciona un archivo (como Test.TXT, cuyo contenido es "Aquí está el contenido de un archivo para cargar") y presiona
Después de que el botón "Confirmar carga" envíe los datos, los datos recibidos por el programa del lado del servidor tendrán el siguiente formato:
--------------------------7cf1d6c47c#13#10
Disposición de contenido: datos de formulario; nombre="Guardar como"#13#10#13#10
Nuevo nombre de archivo#13#10
--------------------------7cf1d6c47c#13#10
Disposición de contenido: formulario-datos; nombre="FileData" nombre de archivo="D: est.txt"
Tipo de contenido: texto/sin formato#13#10#13#10
Aquí está el contenido de un archivo para cargar. #13#10
--------------------------7cf1d6c47c#13#10
Disposición de contenido: datos de formulario; nombre="b1"#13#10#13#10
Confirmar carga#13#10
--------------------------7cf1d6c47c--
Entre ellos, "--------------------------------7cf1d6c47c" es el delimitador utilizado para separar cada campo en el formulario ( Forma);
#13#10 es la representación DELPHI de los caracteres de retorno de carro y avance de línea. Podemos pensarlo de esta manera, la descripción de la información de cada campo del formulario comienza con un delimitador más un par de retornos de carro y avances de línea #13#10 el nombre de dominio del formulario comienza con "nombre="" y termina con """; ; el campo de formulario El valor comienza con dos pares de caracteres de retorno de carro y avance de línea #13#10#13#10, y termina con un par de caracteres de retorno de carro y avance de línea #13#10# más un delimitador; comienza con "filename="" y termina con """ para el final. Con estas banderas, podemos obtener el nombre y el valor del campo del formulario y el nombre del archivo que se cargará, para que los datos del archivo se puedan leer y almacenar.
2. Proceso de implementación de la carga de archivos.
Después de comprender el formato de datos mencionado anteriormente, ya no nos resulta difícil escribir un componente de carga de archivos nosotros mismos.
(1) Iniciar un proyecto para crear un componente ASP
Si no está familiarizado con los pasos para usar DELPHI para desarrollar OLE Automation Server, consulte el artículo "Uso de DELPHI para desarrollar OLE Automation Server para ASP" en "Electrónica y computadoras", edición 06, 1999.
Aquí solo presentamos brevemente los pasos.
1. Cree un proyecto de biblioteca ActiveX
En DELPHI, seleccione el menú Archivo="Nuevo..., seleccione "Biblioteca ActiveX" en la pestaña ActiveX del cuadro de diálogo "Nuevo elemento" y DELPHI creará automáticamente un proyecto DLL PRoject1.
2. Crear componentes de automatización
En DELPHI, seleccione el menú Archivo="Nuevo..., seleccione "Objeto de automatización" en la pestaña ActiveX del cuadro de diálogo "Nuevo elemento"; luego ingrese el nombre de la clase (como "Cargar archivo") en el "Asistente de objetos de automatización". "cuadro de diálogo, instancias seleccione "Múltiples Instancia". Después de hacer clic en "Aceptar", DELPHI creará automáticamente un archivo TLB (Biblioteca de tipos) Proyecto1_TLB.PAS y un archivo PAS (Unidad) Unidad1.PAS. En la ventana de diseño de la Biblioteca de tipos, cambie el nombre de Proyecto1 a MyUpload, luego el código de registro OLE del componente de carga de archivos es "MyUpload.UploadFile".
3. Introducir la biblioteca de tipos ASP
Para utilizar los cinco objetos integrados de ASP (solicitud, respuesta, servidor, aplicación, sesión), es necesario introducir la biblioteca de tipos ASP. Utilizamos principalmente el objeto Solicitud para leer los datos pasados del cliente al servidor.
Seleccione "Biblioteca de tipos de importación" en el menú Proyecto y seleccione "Biblioteca de objetos de páginas de Microsoft Active Server (versión)" en la lista "Bibliotecas de tipos" del cuadro de diálogo "Biblioteca de tipos de importación". 2.0)" (Si esta opción no está disponible, asegúrese de que IIS3 o superior o PWS4 o superior esté instalado en su computadora y que ASP.DLL se haya registrado correctamente), D ELPHI creará automáticamente un archivo TLB ASPTypeLibrary_TLB.PAS, que contiene la declaración de tipo de objeto ASP que necesitamos.
4. Definir los procesos OnStartPage y OnEndPage.
Cuando se utiliza Server.CreateObject para crear una instancia de objeto OLE en una página ASP, el servidor WEB llamará a su método OnStartPage y pasará la información del entorno de la aplicación ASP al objeto. , podemos obtener la información del cliente durante este proceso; cuando se libera una instancia de objeto OLE en la página ASP, el servidor WEB llamará a su método OnEndPage y podemos realizar operaciones finales, como liberar memoria, durante este proceso. En nuestro componente, necesitamos usar su método OnStartPage.
El método OnStartPage debe definirse en Unit1.PAS. El prototipo de función de OnStartPage es:
procedimiento OnStartPage (AScriptingContext: IUnknown);
El parámetro AScriptingContext es una variable de tipo IScriptingContext, que incluye cinco atributos (Solicitud, Respuesta, Servidor, Aplicación, Sesión) correspondientes a cinco objetos integrados del mismo nombre en ASP.
Necesitamos agregar el método OnStartPage a IUploadFile en la ventana de definición de TLB (View="Type Library), y su declaración de Declaración es "procedimiento OnStartPage(AScriptingContext: IUnknown);".
(2) Extraer datos cargados por el cliente
Este trabajo se puede realizar en el proceso OnStartPage.
Usando la propiedad TotalBytes (longitud del contenido de la información de la solicitud) y el método BinaryRead en la propiedad Solicitud (tipo IRequest) de AScriptingContext, los datos de la información de la solicitud cargados por el cliente se pueden leer en una matriz de tipo Byte y luego en el formato de datos definido por RFC1867. estándar para analizar y extraer datos.
1. Primero defina varias variables privadas de TUploadFile
Agregue una referencia a ASPTypeLibrary_TLB.PAS (Usos) en el archivo de unidad UP01.PAS (guardado por Unit1.PAS),
entonces únete
privado
FContentLength: LongInt; // Solicitud de longitud del contenido de información
FContentData: Variante; // Datos de contenido, almacena el contenido de la información de la solicitud en forma de matriz
FFileName, //El nombre del archivo que se cargará
FDelimeter: cadena; //Delimitador de campo de formulario
FScriptingContext: IScriptingContext;//ASP procesa el contenido contextual
FFileDataStart, //Posición inicial de los datos del archivo
FFileDataEnd: LongInt; //Posición final de los datos del archivo
2. Extraer los datos de información de la solicitud cargados por el cliente.
//En el evento OnStartPage, obtenga la información del contexto ASP, solicite el contenido de la información, los delimitadores de campos del formulario y los datos del archivo
procedimiento TUploadFile.OnStartPage(AScriptingContext: IUnknown);
var
ARequest: IRequest; //Objeto de solicitud WWW
AOleVariant: OleVariant; //Registra la longitud del contenido de la información de la solicitud;
intDelimterLength: entero;//Longitud del delimitador
índicelargo,ALongInt,longPos : LongInt;
ContentData: AnsiString;// Representación de cadena del contenido de la información de la solicitud
strTemp: cadena;
FindEndOfFileData: boolean;//Si se encuentra la posición final de los datos del archivo
comenzar
//Extrae los datos de información de la solicitud cargados por el cliente
FScriptingContext := AScriptingContext as IScriptingContext;//Obtener información de contexto ASP
ARequest := FScriptingContext.Request;//Obtener información de solicitud WWW
FContentLength := ARequest.TotalBytes;//Solicitud de longitud del contenido de información
//Crea una matriz dinámica para almacenar el contenido de la información de la solicitud en forma de matriz
FContentData := VarArrayCreate( [0, FContentLength], varByte );
//Almacena el contenido de la información de la solicitud en la matriz
AOleVariant := FContentLength;
FContentData := ARequest.BinaryRead(AOleVariant);//Leer el contenido de la información de la solicitud
//Convierte el contenido de la información de la solicitud en una cadena para facilitar su posicionamiento
Datos de contenido := ';
para longIndex := 0 a FContentLength - 1 hacer
comenzar
ContentData := ContentData + chr( Byte( FContentData[ longIndex ] ));
si FContentData[ longIndex ] = 0 entonces break;//0 indica el final del contenido
fin;
3. Obtenga el delimitador y cargue el nombre del archivo.
//Obtener el delimitador del campo del formulario
longPos := pos( #13#10,ContentData );//La posición del retorno de carro y el carácter de avance de línea
FDelimeter := Copy( ContentData,1,longPos-1);//El contenido antes de esta posición es el delimitador
//Obtiene el nombre del archivo con la ruta de origen. En el contenido de la información de la solicitud, el nombre del archivo comienza con.
//Almacenamiento en forma de nombre de archivo="ruta/nombre de archivo"
strTemp := 'filename="';//El nombre del archivo está después de "filename=""
longPos := pos( strTemp, ContentData );//Obtener la posición "filename=""
si longPos <= 0 entonces
comenzar
NombreDeArchivo := ';
FFileDataStart := -1;
FFileDataEnd := -2;
salida;
fin;
//Obtiene el contenido antes de la siguiente comilla doble """, es decir, el nombre del archivo con la ruta de origen
LongPos := LongPos + longitud( strTemp );
strTemp := ';
para longIndex: = longPos a FContentLength - 1 hacer
si ContentData[longIndex] <> '"' entonces
strTemp := strTemp + ContentData[ índice largo ]
de lo contrario romper;
FFileName := strTemp;
4. Obtenga las posiciones inicial y final de los datos del archivo en el contenido de la información de la solicitud.
//La posición inicial de los datos del archivo es después del primer #13#10#13#10 después del nombre del archivo
eliminar (ContentData, 1, longIndex);
strTemp := #13#10#13#10;
FFileDataStart := longIndex + pos(strTemp, ContentData) + longitud(strTemp) - 1;
//La posición final de los datos del archivo está antes del siguiente #13#10 y el delimitador
//Dado que los datos del archivo pueden contener caracteres ilegales, la función de posicionamiento de cadena POS ya no se puede utilizar.
//Encuentra la posición del siguiente delimitador
FFileDataEnd := FFileDataStart;
intDelimterLength: = longitud (FDelimeter);
FindEndOfFileData: = falso;
mientras que FFileDataEnd <= FContentLength - intDelimterLength lo hace
comenzar
FindEndOfFileData: = verdadero;
para ALongInt: = 0 a intDelimterLength - 1 hacer
si Byte( FDelimeter[ ALongInt + 1 ] ) <>
FContentData[FFileDataEnd + ALongInt] luego
comenzar
FindEndOfFileData: = falso;
romper;
fin;
si FindEndOfFileData entonces se rompe;
FFileDataEnd := FFileDataEnd + 1;
fin;
si no es FindEndOfFileData entonces FFileDataEnd := FFileDataStart - 1//No se encontró ningún delimitador
else FFileDataEnd := FFileDataEnd - 3;//Delimitador, salta hacia adelante #13#10
fin;
(3) Transmitir información al programa ASP
Después de realizar la operación (2), nuestro componente de carga puede pasar datos al programa ASP de acuerdo con sus requisitos. Los datos disponibles actualmente incluyen: nombre del archivo fuente del cliente (FFileName, incluida la ruta), tamaño del archivo (FFileDataEnd-FFileDataStart+1).
Primero, los dos métodos siguientes GetFileName y GetFileSize deben declararse en la ventana de diseño de TLB.
1. Devuelve el nombre del archivo fuente del cliente (incluida la ruta)
//Devuelve el nombre del archivo fuente del cliente (incluida la ruta)
función TUploadFile.GetFileName: OleVariant;
comenzar
resultado := FFileName;//Nombre del archivo fuente del cliente (incluida la ruta)
fin;
2. Tamaño del archivo de devolución
//Tamaño del archivo devuelto (Bytes)
función TUploadFile.GetFileSize: OleVariant;
comenzar
resultado := FFileDataEnd - FFileDataStart + 1;
fin;
(4) Guardar archivos
Después de realizar la operación (2), nuestro componente de carga puede guardar el archivo de acuerdo con los requisitos del programa ASP. Primero debería estar en
Los dos métodos siguientes, SaveFileAs y SaveFile, se declaran en la ventana de diseño de TLB.
1. Guarde el archivo según el nombre de archivo especificado.
// Guarde el archivo según el nombre de archivo especificado. El parámetro FileName es el nombre de archivo especificado. El valor de retorno True indica que el archivo se guardó correctamente.
función TUploadFile.SaveFileAs(Nombre de archivo: OleVariant): OleVariant;
var
índicelargo: Intlargo;
AFile: archivo de bytes;//Guardar el archivo en formato binario
byteDatos: Byte;
comenzar
resultado: = verdadero;
intentar
asignar(AFfile, FileName);
reescribir (un archivo);
para longIndex := FFileDataStart a FFileDataEnd hacer
comenzar
byteData := Byte( FContentData[ longIndex ] );
Escribir(AFile, byteData);
fin;
CerrarArchivo( AArchivo );
excepto
resultado: = falso;
fin;
fin;
2. Guarde el archivo con el nombre de archivo predeterminado.
// Guarde el archivo según el nombre de archivo predeterminado y guarde el archivo con el mismo nombre en el directorio donde se encuentra la página de llamada
función TUploadFile.SaveFile: OleVariant;
var
CurrentFilePath: cadena;
comenzar
//Obtener el directorio donde se encuentra la página de llamada
CurrentFilePath := FScriptingContext.Request.ServerVariables['PATH_TRANSLATED'];
CurrentFilePath: = ExtractFilePath (CurrentFilePath);
// guardar archivo
resultado: = SaveFileAs (CurrentFilePath + ExtractFileName (FFileName));
fin;
3. Ejemplos de aplicación de componentes de carga
En nuestro ejemplo, DelphiUp.HTM es la interfaz de carga de archivos y DelphiUp.ASP se utiliza para realizar operaciones de carga de archivos.
El código de DelphiUp.ASP es el siguiente:
<!--DelphiUp.ASP: Página de procesamiento de carga de archivos-->
<html><head><title>Carga de archivos</title></head><body>
<% carga tenue, nombre de archivo
establecer Cargar = Server.CreateObject("MyUpload.UploadFile")
Nombre de archivo = Cargar.GetNombre de archivo
Response.Write "<br>Guardando archivo ""&FileName&""..."
si Upload.SaveFile entonces
Response.Write "<br>El archivo ""&FileName&"" se cargó correctamente."
Response.Write "<br>El tamaño del archivo es "&Upload.GetFileSize&" bytes."
demás
Response.Write "<br>Archivo ""&FileName&"" no se pudo cargar."
terminar si
configurar Subir=nada %>
</cuerpo></html>
4. Algunas explicaciones
1. El tamaño del archivo DLL compilado a partir del código fuente generado automáticamente por DELPHI es 215K, que se puede encontrar en
En la sección Interfaz de ASPTypeLibrary_TLB.PAS, elimine todas las unidades en Usos excepto ActiveX.
Al eliminar todas las unidades en Usos en MyUpload_TLB.PAS, el tamaño del archivo DLL generado se puede reducir a 61K.
2. El método anterior también es aplicable a programas CGI, pero se debe utilizar el objeto TWebRequest.
El programa anterior fue depurado y aprobado bajo PWIN98+Delphi3.0+PWS4.0.