[Indice]


El objeto Response

Response (respuesta) es posiblemente el objeto más utilizado de todos, ya que sirve para presentar en la pantalla del navegador del cliente el resultado de cualquier código que hayamos escrito.

El objeto Response tiene 8 propiedades, 1 colección y 8 métodos:


PROPIEDADES

Response.Buffer = False | True

Cuando ASP procesa una página cualquiera, va ejecutando comandos, adjunta código HTML, lee ficheros de inclusión, etc., y todo eso, hasta que la respuesta está completa lo va guardando en un buffer (un buffer es un área temporal de trabajo). A este proceso se le denomina buffering. Cuando la composición del fichero de respuesta está completa, o entre los comandos ejecutados encuentra una llamada a los métodos Flush o End, ASP concluye el proceso de buffering, envía el fichero de respuesta al cliente y vacía el buffer, quedando a la espera del siguiente proceso.

La propiedad Response.Buffer sirve para intervenir en el proceso de buffering. Si el valor de Buffer es True, el servidor enviará el contenido del buffer a la salida, pero si es False, el proceso de buffering no se realiza. Esto significa que no es posible cambiar la propiedad después de que el servidor haya enviado la respuesta. Si se quiere evitar el buffering, habrá que hacerlo antes de que éste comience, por lo que la instrucción deberá ser la primera de todas.

El valor por defecto de Buffer en ASP 2.0 es False. En la versión 3.0 es True, siempre que se realice una instalación nueva, si es una actualización, quedará con el valor antiguo, es decir, False.


Response.CacheControl = "Public" | "Private"

Esta propiedad permite a los servidores proxy guardar o no en su cache una copia de la respuesta ASP. Vale... no sabes que es un "proxy" ni una "cache". Veamos: un servidor proxy, es una máquina que se instala en algunas redes locales (también llamadas intranets) y cuya función, entre otras, consiste en guardar en sus discos una copia de todas las páginas web que han visitado los navegadores de esa red local. A esto se le llama guardar en cache. Esto mismo ya lo hace también el navegador en la propia máquina donde esté instalado. El navegador tiene dos caches: en memoria y en disco, y es configurable por el usuario el tamaño de ambas, así como el tiempo que las páginas visitadas permanecerán en ellas. La finalidad de todo esto, que a algunos les podrá parecer un atentado a su intimidad, es conseguir que las páginas de uso más habitual se carguen más rápidamente, ya que al residir en las caches, del navegador o del proxy, no es necesario salir a internet para cargarlas de nuevo desde el servidor original. En fin, si las redes fueran lo rápidas que debieran y las conexiones costasen menos dinero, seguramente todo esto no sería necesario.

Esto de los proxy está muy bien si hablamos de HTML estático, pero si hablamos de ASP dinámico, es decir, páginas que cada vez que son llamadas pueden tener un contenido diferente, pero con el problema de que siempre tienen el mismo nombre, que es precisamente, en función de lo que el proxy decide si servir de la cache o conectarnos con el servidor original, pueden ser un grave problema.

Imagina que tu aplicación tiene una página que muestra los datos de un cliente previamente identificado, por ejemplo su ficha personal con domicilio, teléfono, cuenta bancaria de cargo, etc. La página tiene como nombre, por ejemplo, cliente.asp. Un cliente hace un request solicitando la página después de identificarse. El servidor envia la página solicitada, y el proxy, cumpliendo con su función, guarda en cache una copia. Lo mismo hace el navegador de la máquina desde donde se hace el request, y supongamos también que esa máquina está en una sala pública de terminales muy concurrida. Si... se adivina un desastre. En efecto, el cliente ha terminado sus transacciones y se marcha. Otro cliente, que estaba esperando su turno, se sienta ante la misma máquina... y cómo no, se conecta a la misma aplicación. La primera pantalla no es peligrosa, ya que son instrucciones. La segunda, tampoco, es un formulario donde hay que escribir la identificación... pero la tercera es cliente.asp que muestra la ficha con los datos personales.

¿Qué va a ocurrir? Apenas han transcurrido unos segundos desde que el anterior cliente hizo el mismo request. Aunque hubiesen pasados minutos, la situación sería la misma. Las caches del navegador están configuradas para ser eliminadas cada dia (eso con suerte), la del proxi, lo mismo, y éste solamente hará una verificación de fechas para ver si el original ha cambiado o no, y no lo ha hecho. Por tanto la cosa está clara: al segundo cliente le aparecerá la ficha personal del primero, y sólo cuando pulse el botón "recargar" del navegador, forzará al navegador y al proxy a conectarle con el servidor, obteniendo sus datos correctos. Pero mientras, hemos dejado que nuestra aplicación muestre unos datos indebidamente, lo cual es muy grave.

Para evitar que el proxy copie en su cache las respuestas de nuestros ASP, se puede utilizar la propiedad Response.CacheControl . Hay otras dos propiedades: Response.Expires y Response.ExpiresAbsolute que controlan las caches, pero éstas lo hacen sobre las del navegador.

Si se escribe:

<% Response.CacheControl = "Public" %> SI guarda en cache del proxy (por defecto)
<% Response.CacheControl = "Private" %> NO guarda en cache del proxy


Response.Charset("String")

Esta propiedad añade el nombre de la tabla de caracteres al contenido del objeto Response, concretamente como parámetro de content-type. El valor por defecto es ISO-LATIN-1 (excepto en entornos Macintosh).

Por ejemplo, una cabecera HTTP normal contiene el siguiente string:

  content-type: text/html

Y después de escribir

<% Response.Charset("MS_Windows") %>

Contendría:

  content-type: text/html; charset = MS_Windows

Hay que tener en cuenta que como argumento se puede escribir cualquier cosa, y aunque no sea válido, ASP no emite ningún mensaje de error, simplemente no surtirá el efecto deseado.


Response.ContentType("String")

Esta propiedad especifica el tipo de contenido del request HTTP, que puede incluir un tipo/subtipo en la cabecera de la respuesta. El tipo siempre es de contenido general y el subtipo es específico. El valor por defecto es text/HTML. Tiene que ir antes de que se defina la cabecera de la página.

Por ejemplo, el siguiente código poduce una hoja de cálculo Excel en el navegador, simpre que Excel esté instalado en la máquina del cliente, claro.

<% Response.ContentType = "application/vnd.ms-excel" %>
<HTML>
<HEAD><TITLE>PRUEBA</TITLE></HEAD>
<BODY>
<TABLE>
<TR><TD>Valor de la celda A1</TD>
    <TD>Valor de la celda B1</TD>
</TR>
<TR><TD>Valor de la celda A2</TD>
    <TD>Valor de la celda B2</TD>
</TR>
</TABLE>
</BODY>
</HTML>


Response.Expires

La propiedad Expires indica el número de minutos que deben transcurrir antes de que la copia de la respuesta en las caches del navegador expire (sea eliminada). Fíjate en que se refiere a la cache del navegador, no a la del servidor proxy (si lo hubiese). Si no se invoca esta propiedad, el tiempo de expiración será el que tenga configurado el navegador por defecto.

Si se escribe:

<% Response.Expires = 0 %>

Esto significa que la página expira inmediatamente después de su recepción y visualización en el navegador. Si en lugar de cero se escribe, por ejemplo, 2, significará que dos minutos después de haberse recibido, el navegador eliminará la página de su cache.

El tiempo de expiración en la cache del navegador, hay que usarlo con precaución, ya que si la página está destinada a ser impresa (por ejemplo es el resguardo de una operación realizada por el cliente) y ha expirado, el navegador no podrá enviarla a la impresora, y emitirá un mensaje de error diciendo que no hay datos que imprimir, incluso aunque en ese momento la página sea visible en la pantalla, pero no es de esa imagen de donde el navegador envia datos a la impresora, sino de su cache en disco. Esto significa que hay que pensar cuidadosamente que páginas terminarán siendo impresas y cuales no en el momento de utilizar esta propiedad.


Response.ExpiresAbsolute

Funciona igual que la anterior, pero en lugar de indicar el número de minutos que deben transcurrir antes de que las caches del navegador expiren, indica la fecha y hora exacta en que eso ocurrirá. No es muy fiable, ya que no sabemos si la fecha y hora del cliente son correctas, y también habrá que tener en cuenta la hora del país desde donde el cliente nos hace el request, para que sea mínimamente efectiva.

Se escribe:

<% Response.Expires = #Feb 20, 2000 20:00:00# %>


Response.IsClientConnected = True | False

Con esta propiedad se puede saber si el cliente continua conectado al servidor desde la última vez que se utilizó la propiedad Response.Write, es decir desde la última vez que nuestra aplicación ha escrito algo en la pantalla del cliente. Puede ser muy útil si el proceso solicitado va a ser muy trabajoso para el servidor, por ejemplo una consulta a una DB que devolverá gran cantidad de datos. Si se verifica que el servidor a perdido la conexión con el cliente, es inútil hacer todo el trabajo solicitado por éste, ya que no se podrá enviar el resultado, y además el servidor entrará en una fase de reintentos sucesivos, hasta que el tiempo de cierre de sesión especificado en su configuración se cumpla. Si eso ocurre con muchos procesos a la vez, el servidor puede bloquearse.

Por ejemplo:

<%
'--Se abren conexiones a la DB y/o se preparan procesos.
      ...
      ...
'--Mediante un bucle se verifica si el cliente sigue conectado, o si los procesos han terminado

Do until (PROCESOS ACTIVOS... OR Response.IsClientConnected=false)

'--- si el cliente sigue conectado, se hacen los procesos necesarios
      ...
      ...
Loop

'---Procesos terminados o conexión perdida. Se cierran las conexiones y se liberan recursos
      ...
      ...
%>


Response.Status = "Status"

Esta propiedad especifica el valor de la línea de estado HTTP devuelta por el servidor. Normalmente consiste en la dirección IP del cliente que ha provocado el estado, seguida de una breve descripción de error. Esto hay que escribirlo antes que cualquier otra línea de la página.

Si se desea impedir el acceso a la aplicación a una máquina cuyo IP sea, por ejemplo, 125.125.125.125 escribiremos:

<%
Dir_IP = Request.ServerVariables("REMOTE_ADDR")
If Dir_IP = "125.125.125.125" Then
   Response.Status = "403 Acceso prohibido"
   Response.Write Response.Status
   Response.End
End If
%>
<HTML>
<HEAD><TITLE>PRUEBA</TITLE></HEAD>
<BODY>
..
..

Esto mismo se puede configurar en el servidor de forma fija, en el apartado de seguridad de la aplicación.


COLECCIONES

Response.Cookies(Nombre)[(Clave)|.Atributo]=Valor

Esta colección funciona básicamente igual, y sirve para lo mismo, que la ya explicada en el objeto Request, pero aquí podemos asignar los valores que se estimen necesarios para la aplicación. Tiene dos argumentos obligatorios: Nombre que es el nombre que se le asigna al cookie, y Valor que especifica el contenido asignado a la clave o atributo.

También tiene dos argumentos opcionales: Atributo, que puede consistir en cinco parámetros preestablecidos diferentes, y clave, que como su nombre indica, es la clave que se le asigna al atributo Valor

Los parámetros preestablecidos de Atributo pueden ser los siguientes:

He aquí un ejemplo:

<%@ LANGUAGE="VBScript" %>
<% 
   Response.Cookies("test").Expires = "31/05/05"
   Response.Cookies("test")("item1") = "prueba" 
   Response.Cookies("test")("Contador") = Request.Cookies("test")("Contador") + 1
%>

<HTML>
<HEAD><TITLE>pruebas cookies</TITLE></HEAD>
<BODY>

Contador: <% = Request.Cookies("test")("Contador") %><BR>
Cookie: <% = Request.Cookies("test") %>

</BODY>
</HTML>
Y este sería el resultado:

Contador: 1
Cookie: CONTADOR=1&ITEM1=prueba

En este ejemplo, Contador se incrementa en 1 cada vez que la página es cargada por el navegador. La primera vez valdrá 1, la segunda 2, etc. Cuando el cookie no existe o haya expirado, el contador vuelve a 1 en la siguiente visita.

Recuerda que todas las instrucciones para crear o modificar los cookies hay que escribirlas siempre antes de cualquier otra cosa de la página. Otra cosa importante que no hay que olvidar es que nunca deben ponerse datos confidenciales en los cookies, ya que los ficheros se quedarán en la máquina del cliente, incluso después de haber expirado, y otro usuario podría llegar a ellos.

En los cookies se pueden guardar datos muy variados, como contadores, preferencias del cliente, colores, resoluciones, etc., y no se deben utilizar de forma maliciosa (spiware), pero recuerda que son datos que afectan solamente a una máquina física, y que los datos de un usuario no estarán disponibles si se conecta desde otra máquina.

Cada navegador genera y guarda los cookies de una manera diferente. Los del Internet Explores de Microsoft suelen estar en C:\WINDOWS\Cookies (Win95, 98 y ME). Si se trata de Win NT, 2000, 2003 o XP estarán en C:\Documents and Settings\nombre_usuario\Cookies.


METODOS

Response.AddHeader "Nombre", "Valor"

Este método permite añadir una nueva cabecera a la respuesta HTTP. Una vez que la cabecera ha sido creada, no es posible borrarla. El nombre dado a la nueva cabecera no puede contener ningun carácter de subrayado ( _ )

Se escribe:

<%
Response.AddHeader "MiCabecera", "PRUEBA"
%>


Response.AppendToLog("String")

Mediante este método se puede añadir un string al registro que se genera con cada request en el fichero de logs del IIS.

Por ejemplo:

<%
Response.AppendToLog("Mi comentario")
%>

Y este sería el string añadido en un registro típico del fichero de logs del IIS:

125.125.125.125, - , 05/27/99, 9:50:00, W3SVC, PRUEBAS, 125.125.125.125, Mi comentario


Response.BinaryWrite(Data)

Escribe la salida HTTP en binario (no en modo string como lo hace Response.Write), y sin aplicar ninguna conversión de página de caracteres.

Supongamos que tenemos el siguiente formulario HTML con tres campos:

'---Fichero formulario.htm
<HTML><HEAD> <TITLE>Prueba1 ASP</TITLE> </HEAD>
<BODY>
<FORM ACTION="prueba2.asp" METHOD="POST">
Nombre:<INPUT TYPE="text" NAME="Nombre" VALUE="Juan" ><br>
Ciudad:<INPUT TYPE="text" NAME="Ciudad" VALUE="Guadalajara" ><br>
Postal:<INPUT TYPE="text" NAME="Postal" VALUE="12345"       ><br>
<INPUT TYPE="Submit" NAME="Boton" VALUE="Enviar">
</FORM>
</BODY>
</HTML>

Para poder ver el nombre de los campos y sus contenidos se escribe lo siguiente:

'---Fichero prueba2.asp
<%
bytecount = Request.TotalBytes
binread = Request.BinaryRead(bytecount)
Response.BinaryWrite binread
%>

Y este sería el resultado:

Nombre=Juan&Ciudad=Guadalajara&Postal=12345&Boton=Enviar


Response.Clear

Este método se utiliza para vaciar (borrar) cualquier contenido del buffer de salida. No elimina las cabeceras HTTP, solamente el contenido que va entre los elementos <BODY> y </BODY> Si el buffer ya está vacío debido a que previamente se ha invocado Response.Buffer=False, se produce un error de ejecución. Recuerda que en la versión 2.0 de ASP el valor por defecto de Response.Buffer es False y en la versión 3.0 es True.

Se escribe:

<%
Response.Clear
%>


Response.End

Cuando se invoca este método el servidor detiene el proceso de la página ASP actual y envia al cliente el contenido del buffer de salida, siempre que Response.Buffer=True. El resto de instrucciones no se procesará. Recordar que en la versión 2.0 de ASP el valor por defecto de Response.Buffer es False y en la versión 3.0 es True.

Por ejemplo, si se escribe:

<%
Response.Write "Primer string"
Response.End
Response.Write "Segundo string"
%>

Sólo se obtiene en la respuesta:
Primer string


Response.Flush

Este método provoca el envio inmediato al cliente del contenido del buffer de salida, en lugar de hacerlo al concluir el proceso completo de la página, y continuando después con el resto de instrucciones normalmente. Si el buffer está vacío debido a que previamente se ha invocado Response.Buffer=False, se produce un error de ejecución. Recuerda que en la versión 2.0 de ASP el valor por defecto de Response.Buffer es False y en la versión 3.0 es True.

Se escribe:

<%
Response.Flush
%>


Response.Redirect(URL)

Este método detiene el proceso de las instrucciones de la página actual e intenta conectar el cliente a una nueva dirección (URL). Esto se consigue añadiendo una cabecera de redirección a la salida HTTP que se envia al cliente. Puede haber un problema en el caso de que alguna parte de la página ya haya sido enviado al cliente mediante alguno de los dos anteriores métodos (Flush o End) si entre el servidor web y el cliente hay un servidor proxy, por lo que debe usarse con precaución.

He aquí un ejemplo de uso:

'---Fichero1.asp
<% Response.Buffer = true %>
<HTML>
<BODY>
<%
Response.Write "Este es Fichero1.asp y se conmuta con Fichero2.asp"
Response.Clear
Response.Redirect "Fichero2.asp"
Response.Write "Esto ya no se procesa"
%>
</BODY>
</HTML>

'---Fichero2.asp
<HTML>
<BODY>
<%
Response.Write "Este es Fichero2.asp"
%>
</BODY>
</HTML>

Este sería el resultado: se muestra parte de Fichero1 y el navegador es obligado a cargar Fichero2:

'---Fichero1.asp
Este es Fichero1.asp y se conmuta con Fichero2.asp
 
'---Fichero2.asp
Este es Fichero2.asp


Response.Write(Valores)

Llegamos al último método del objeto Response. Como ya sabes, puesto que se ha venido utilizando en la explicación de otros objetos, sirve para escribir el resultado del código ASP en el navegador del cliente. Se habló más a fondo de él en la página ¿Cómo se escribe el ASP?

Se escribe:

<%
Response.Write(Valores)
%>


[Indice]