6 Analysis and Discussion
7.1 Positioning technologies
A continuación se ofrece una breve descripción de todos los métodos que presenta el objeto integrado Server, al lo largo de este apartado iremos profundizando en cada uno de ellos.
• CreateObject: método por excelencia del objeto Server, crea una instancia de un componente. Este componente debe estar registrado en el servidor Web.
• HTMLEncode: devuelve una cadena codificada en HTML a partir de la cadena que se le pasa como parámetro.
• MapPath: devuelve la ruta física de una ruta virtual dada a través de una cadena en formato URL.
• URLEncode: devuelve una cadena a la que se le ha aplicado la codificación URL correspondiente a las cadenas de consulta (QueryString).
• URLPathEncode: devuelve una cadena a la que se le ha aplicado la codificación URL correspondiente a las cadenas de rutas.
• Execute: para la ejecución de la página actual y transfiere la ejecución a la página indicada. Una vez que ha finalizado la ejecución de la nueva página, la ejecución continúa en la página inicial.
• Transfer: finaliza la ejecución de la página actual y transfiere la ejecución a la página indicada por parámetro. Sin volver en ningún caso a la página original.
• GetLastError: devuelve una referencia al objeto ASPError que contiene la información detallada del último error que se ha producido.
Los cuatro últimos métodos han sido añadidos en la versión 3.0 de ASP.
CreateObject
Es el método más utilizado del objeto Server, posiblemente, sea el método CreateObject. Este método permite la instanciación de componentes de servidor, para que a continuación sean manipulados por las secuencias de comandos de nuestras páginas ASP. Para crear una instancia de un componente de servidor se debe utilizar la sintaxis general:
Set nombreObjeto=Server.CreateObject(ProgID)
La palabra reservada Set siempre se debe utilizar en la instanciación de un objeto y ProgID es el nombre con el que está registrado el objeto en el servidor, el formato para ProgID es: [Fabricante.]Componente[.Versión]. Así por ejemplo el ProgID de el objeto Recordset del modelo de objetos de acceso a datos ActiveX Data Objects (ADO) es ADODB.Recordset.
La variable nombreObjeto debe tener un nombre distinto de cualquiera de los objetos integrados de ASP. Se puede destruir un objeto asignándole Nothing, de esta forma se libera la memoria ocupada por el objeto.
Las instancias de un objeto, por defecto, se destruyen cuando la página ASP termina de ser procesada, aunque es más seguro destruirlas mediante la palabra reservada Nothing.
<%Set nombreObjeto=Nothing%>
Código fuente 134
Para crear un objeto con ámbito de sesión o de aplicación se debe almacenar el objeto en una variable de sesión o de aplicación, o bien utilizando la etiqueta de HTML <OBJECT> en el fichero global.asa y asignando al parámetro SCOPE los valores Session o Application, como vimos en el capítulo anterior. De esta forma el objeto se destruirá cuando haya finalizado la sesión o la aplicación.
Así por ejemplo, si queremos crear una conexión a una base de datos, utilizando un componente ActiveX Server de manejo de bases de datos, y que tenga el ámbito de una sesión, se deberá escribir el Código fuente 135.
<%Set Session("conexion")=Server.CreateObject("ADODB.Connection")%> Código fuente 135
No es demasiado recomendable utilizar objetos a nivel de sesión o aplicación, y si se utilizan se deben destruir cuanto antes, ya que pueden suponer una gran carga para la memoria del servidor Web. Es preferible crear y destruir un objeto varias veces que llevar su referencia almacenada en una variable de sesión o de aplicación.
En el Código fuente 136 se muestra la utilización del método CreateObject para utilizar un componente de VBScript. Se trata de crear una instancia de un componente FileSystemObject para mostrar los datos de un fichero del servidor.
<%Set objficheroSistema=Server.CreateObject("Scripting.FileSystemObject") Set fichero=objficheroSistema.GetFile("e:\tmp\coleccio.zip")%>
Fecha creación: <%=fichero.DateCreated%><br> Nombre: <%=fichero.Name%><br> Tamaño: <%=fichero.Size%><br> Tipo: <%=fichero.Type%><br> <%Set fichero=Nothing Set objficheroSistema=Nothing%> Código fuente 136 El resultado es: Fecha creación: 25/05/2000 15:26:48 Nombre: coleccio.zip Tamaño: 1043445 Tipo: WinZip File
Una vez creado el objeto podemos utilizar todos sus métodos, propiedades y colecciones. En el capítulo dedicado a los componentes de VBScript trataremos todos ellos en detalle.
MapPath
El método MapPath devuelve la ruta física que se corresponde con el la ruta virtual que se le pasa por parámetro. El objeto Server posee información sobre los directorios físicos, virtuales y relativos de la máquina servidor y sabe como debe realizar la traducción de rutas virtuales a físicas. Se puede necesitar obtener rutas físicas cuando se quieran crear directorios o manipular ficheros en el servidor. La forma de utilizar este método es la siguiente:
nombreVariable=Server.MapPath(rutaVirtual)
Dónde rutaVirtual contiene el ruta virtual del directorio o fichero del que se desea obtener su ruta física y nombreVariable contendrá la ruta física correspondiente.
Si la ruta que se le pasa como parámetro al método MapPath empieza con una barra (/ o \), el método traduce la ruta desde el directorio raíz del servidor hasta el directorio virtual especificado. Por otro lado, si no posee barra se traducirá de forma relativa al directorio dónde reside la página ASP que ha realizado la llamada al método.
Así por ejemplo, si el directorio inicial del servidor (directorio de publicación en Internet) está establecido como el directorio c:\inetpub\wwwroot, y si tenemos una página ASP ejecutándose en el directorio c:\inetpub\wwwroot\cursoASP30 y escribimos el Código fuente 137 para mapear la ruta de un fichero llamado FICH.TXT que se encuentra en el mismo directorio que la página ASP:
<%=Server.MapPath("/scripts/fich.txt")%><br> <%=Server.MapPath("scripts/fich.txt")%>
Código fuente 137
Se obtendrá en el navegador la siguiente salida:
C:\inetpub\wwwroot\scripts\fich.txt
C:\inetpub\wwwroot\cursoASP\scripts\fich.txt
El método MapPath no comprueba si la ruta virtual que le pasamos por parámetro existe en el servidor. Para saber la ruta virtual de la página actual el servidor utiliza una variable llamada PATH_INFO incluida en la colección ServerVariables del objeto Request. Para obtener el valor de la ruta física de la página ASP actual deberemos escribir el Código fuente 138 dentro de la página ASP.
<%=Server.MapPath(Request.ServerVariables("PATH_INFO"))%>
Código fuente 138
Y si escribimos el Código fuente 139 obtendremos la ruta física del directorio inicial del servidor Web, es decir, el directorio del que cuelga toda la publicación en Internet.
<%=Server.MapPath("/")%>
Se recomienda por eficiencia evitar el uso del método MapPath, cada llamada a este método supone una nueva conexión al servidor Web para que IIS devuelva la ruta actual del servidor. En su lugar es más rápido utilizar la ruta literal, si se conoce, de esta forma en el ejemplo anterior, si queremos acceder al fichero fich.txt deberemos escribir su ruta completa: C:\inetpub\wwwroot\scripts\fich.txt.
HTMLEncode
El método HTMLEncode devuelve una cadena a la que se le ha aplicado la codificación HTML a partir de la cadena que se le pasa por parámetro.
Este método se suele utilizar para mostrar texto en le navegador sin que sea interpretado por el mismo como si fuera HTML, veamos un sencillo ejemplo, en el Código fuente 140.
<%Response.Write "<b>Cadena en HTML</b>"%><br>
<%Response.Write Server.HTMLEncode("<b>Cadena en HTML</b>")%><br>
Código fuente 140
La salida de esta página será:
Cadena en HTML
<b>Cadena en HTML<b>
Es decir, en el primer caso el navegador interpreta las etiquetas <B> de HTML, y por ello muestra el texto en negrita, y la segunda sentencia aplica el método HTMLEncode y de esta forma se evita que el navegador trate las etiquetas HTML, y muestra todo como un texto normal, si vemos el código de la página HTML generada podemos ver lo que muestra el Código fuente 141.
<b>Cadena en HTML</b><br>
<b>Cadena en HTML</b><br>
Código fuente 141
URLEncode
El método URLEncode se utiliza para aplicar la codificación URL a la cadena que se le pasa como parámetro, devolviendo la cadena resultante de realizar dicha codificación. LA codificación URL que se aplica es la perteneciente a las cadenas de consulta, es decir, la información que se sitúa en una URL a partir del caracter ?, lo que en ASP se representa mediante el objeto integrado QueryString. Existen una serie de caracteres ASCII que se codificarán de forma hexadecimal dentro de la codificación URL, a estos códigos hexadecimales les precederá el símbolo %. Por ejemplo el símbolo < se codificará como %3C, el espacio en blanco como %20 y la arroba (@) como %40.
Dentro de la codificación de las cadenas de consulta existen una serie de caracteres reservados que tienen un significado especial, en la Tabla 15 se muestran estos caracteres.
Caracter Función en la codificación URL de la cadena de consulta
+ Separar datos.
= Relaciona el nombre de un parámetro con su valor & Separa pares parámetro/valor
% Indica que el caracter se ha codificado utilizando la codificación hexadecimal
Tabla 15
Este método se suele utilizar cuando debemos pasar una cadena a través de una cadena de consulta de una página y posee caracteres especiales como puede ser blancos, tildes, etc. El navegador Internet Explorer suele realizar la transformación a la codificación URL de forma automática, pero Netscape no lo hace y además puede producir errores.
Si queremos utilizar un enlace con un QueryString que posea un parámetro llamado nombre, deberemos hacer lo que indica el Código fuente 142.
<a href="Pagina.asp?nombre=<%=Server.URLEncode("Angel Esteban Núñez")%>">Enlace</a>
Código fuente 142
En la barra de direcciones del navegador al pulsar sobre el enlace aparecerá la siguiente codificación URL:
http://aesteban/cursoasp30/Pagina.asp?nombre=Angel+Esteban+N%FA%F1ez
URLPathEncode
Si leemos la documentación en relación a ASP que ofrece Microsoft con el servidor Web Internet Information Server 5, vemos que este método del objeto Server no aparece, sin embargo si lo descubrimos utilizando la facilidad intellisense, que ofrece Visual InterDev, sobre le objeto Server. Este método no documentado es muy similar a URLEncode, aplica la codificación URL pero no para cadenas de consulta, sino para caminos virtuales y direcciones URL. La diferencia entre el método anterior y éste se ve en el Código fuente 143.
Server.URLEncode: <%=Server.URLEncode("http://www.almagesto.com")%><br>
Server.URLPathEncode: <%=Server.URLPathEncode("http://www.almagesto.com")%><br>
Código fuente 143
Server.URLEncode: http%3A%2F%2Fwww%2Ealmagesto%2Ecom Server.URLPathEncode: http://www.almagesto.com
Este método puede ser útil para utilizar con direcciones de Internet que posean caracteres especiales, como por ejemplo blancos o tildes, aunque esto no suele ser habitual.
Execute
Cuando tratamos el objeto Response en su capítulo correspondiente vimos que presentaba un método llamado Redirect que nos permitía pasar a ejecutar una página distinta, pero esto suponía enviar una respuesta al cliente para indicarle la carga de una nueva página, que es la página a la que pasamos la ejecución, el aspecto de las cabeceras HTTP que se envían al cliente podría ser:
HTTP/1.1 Object Moved
Location /directorio/pagina.asp
La utilización del método Redirect es bastante costosa y problemática ya supone un envío de información más del servidor al cliente para indicarle mediante una cabecera HTTP de redirección que la página ha cambiado de localización, siendo la nueva localización la página que deseamos cargar. Esto es problemático ya que en algunos navegadores como Netscape Communicator aparace un mensaje del tipo El objeto requerido se ha movido y se puede encontrar aquí, esto también
ocurre cuando la conexión la realiza el cliente a través de proxy.
Pero mediante los métodos Execute y Transfer podemos evitar esta redirección, que como hemos visto, tiene lugar en el cliente. Estos dos métodos permiten que la redirección tenga lugar en el servidor, quedando el cliente completamente ajeno. Ambos métodos reciben como parámetro la ruta de la página a la que queremos redirigir al cliente.
La utilización del método Execute es muy similar a realizar una llamada a un procedimiento o función. Cuando lanzamos el método Execute se empieza a ejecutar la página que indicamos por parámetro, y cuando termina la ejecución de esta nueva página, el control pasa a la siguiente sentencia después de la llamada al método Execute en la página inicial, siguiendo a partir de aquí con la ejecución de la página, es decir, el navegador del cliente recibe una salida formada por la combinación de la ejecución de ambas páginas.
Esto se ilustra con un sencillo ejemplo, la primera página llamada PAGINAORIGINAL.ASP, en un punto determinado hace una llamada a Server.Execute para ejecutar OTRAPAGINA.ASP, una vez terminada la ejecución de OTRAPAGINA.ASP, se sigue con la siguiente sentencia a Server.Execute en la página paginaORIGINAL.ASP. Veamos el Código fuente 144 y el Código fuente 145.
<%@ Language=VBScript %> <HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> </HEAD>
<BODY>
<b>Estás en la página inicial</b><br>
Server.ScriptTimeout=<%=Server.ScriptTimeout%><br> <%Server.Execute "otraPagina.asp"
Response.Write "he vuelto de la ejecución"%> </BODY>
</HTML>
<%@ Language=VBScript %> <HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> </HEAD>
<BODY>
<table border="1"> <tr><td>
Estás en la otra página<br> <b><%=Date%></b><br> <b><%=Time%></b><br> </td></tr> </table> </BODY> </HTML> Código fuente 145
El resultado de la ejecución de esta página se puede ver en la Figura 38.
Figura 38. Utilización del método Execute
El cliente ni siquiera observa la URL correspondiente a la página otraPagina.asp ya que la redirección entre páginas se produce en el servidor, el navegador cree que sigue recibiendo todavía la página original que habia demandado, incluso en la barra de direcciones del navegador sigue apareciendo la misma URL y los botones Atrás y Adelante funcionan correctamente.
En ambos métodos se mantiene el contexto de la página inicial, es decir, en la nueva página tenemos acceso a las variables, objetos y a todos los objetos intrínsecos de ASP (Request, Session, Response...) de la página inicial o página de origen. Si modificamos la página otraPagina.asp y mostramos el contenido de la variable SCRIPT_NAME de la colección ServerVaribles del objeto Request, veremos que tiene el valor que se corresponde con el de la página original.
<%@ Language=VBScript %> <HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> </HEAD>
<BODY>
<table border="1"> <tr><td>
Estás en la otra página<br> <b><%=Date%></b><br>
<b><%=Time%></b><br>
Sin embargo Request.ServerVariables("SCRIPT_NAME")= <%=Request.ServerVariables("SCRIPT_NAME")%> </td></tr> </table> </BODY> </HTML> Código fuente 146
Y el nuevo resultado demuestra que se mantiene el contexto de la página ASP de origen.
Figura 39. Se mantiene el contexto entre páginas
Transfer
El método Transfer también permite la redirección entre páginas en el servidor, pero este método se comporta de distinto modo al método Execute, al lanzar este método se pasa la ejecución a la nueva página, pero una vez que finaliza la ejecución de la misma no se vuelve a la página inicial, como ocurría con el método Execute. El método Transfer es bastante más parecido al método Redirect que lo era el método Execute, ya que con Transfer al igual que con Redirect no se regresa a la página original.
Con el método Transfer se sigue manteniendo el contexto de la página inicial entre las distintas páginas. Para ver como funciona el método Transfer vamos a utilizar el ejemplo anterior y
simplemente vamos a cambiar la llamada a Execute por Transfer. El resultado que se obtiene es el que nos muestra la Figura 40.
Figura 40. Utilizando el método Transfer
Como se puede comprobar la única diferencia es que la ejecución finaliza cuando termina la ejecución de la segunda página y no se vuelve a la inicial.
GetLastError
Mediante el uso del método GetLastError podemos tener acceso a toda la información referente al último error que se ha producido en la página ASP actual. Pero es necesario aclarar que su utilización no es similar al tratamiento de errores que realizábamos con la sentencia On Error Resume Next y el objeto Err de VBScritp, que preguntábamos por la propiedad Number del objeto Err para averiguar si se había producido algún error.
El método GetLastError se puede utilizar únicamente dentro de una página de error personalizada, es decir, cuando el error ya se ha producido y lo ha detectado el servidor Web.
Mediante el servidor Web Internet Information Server 5 podemos indicar las páginas de error personalizadas y es en estas páginas dónde podemos hacer uso de este método.
El método GetLastError devuelve un nuevo objeto del modelo de objetos de ASP llamado ASPError, son las propiedades de este nuevo objeto las que nos permiten acceder de forma detallada a toda la información referente al error que se ha producido. Este nuevo objeto lo trataremos con más detalle en el capítulo correspondiente, también veremos como configurar las páginas de error personalizadas desde IIS5.
Con este método terminamos la exposición del objeto Server, ya que no ofrece ninguna colección. Pero antes de terminar este capítulo vamos a ver un ejemplo que resume la utilización de todos los métodos del objeto Server.
Este ejemplo se trata de un formulario con diversos campos, cada uno de ellos se corresponde con un método del objeto Server. Para seleccionar el método que deseamos utilizar se debe seleccionar con el botón de radio correspondiente y acto seguido se debe pulsar el botón etiquetado como Ejecutar, que se trata de un campo de tipo submit del formulario.
En el caso de la ejecución del método Transfer y Execute se debe indicar la página que se desea ejecutar en cada caso, con los métodos URLEncode, URLPathEncode y HTMLEncode se debe indicar una cadena a la que se quiere aplicar la codificación correspondiente, para utilizar el método MapPath se debe indicar una ruta virtual para obtener la ruta física correspondiente, y en el caso del método CreateObject se debe indicar una cadena que represente un ProgID válido para el componente que se