You are on page 1of 193

Webmasters

Curso de HTML
1. ESTRUCTURA BASICA DE UN DOCUMENTO HTML

El principio esencial del lenguaje HTML es el uso de las etiquetas (tags). Funcionan de la siguiente
manera:

<XXX> Este es el inicio de una etiqueta.

</XXX> Este es el cierre de una etiqueta.

Las letras de la etiqueta pueden estar en mayúsculas o minúsculas, indiferentemente.

Lo que haya entre ambas etiquetas estará influenciada por ellas. Por ejemplo, todo el documento
HTML debe estar entre las etiquetas <HTML> y </HTML>:

<HTML> [Todo el documento] </HTML>

Un documento HTML en sí está dividido en dos zonas principales:

o El encabezamiento, comprendido entre las etiquetas <HEAD> y </HEAD>


o El cuerpo, comprendido entre las etiquetas <BODY> y </BODY>

Dentro del encabezamiento hay información del documento, que no se ve en la pantalla principal
del BROWSER que es utilizado para visualizar el documento HTML, principalmente la información
encontrada en el encabezamiento es el título del documento, comprendido entre las etiquetas
<TITLE> y </TITLE>. El título debe ser breve y descriptivo de su contenido, pues será lo que vean
los demás cuando añadan nuestra página a su bookmark (o agenda de direcciones).

Dentro del cuerpo está todo lo que queremos que aparezca en la pantalla principal (texto,
imágenes, etc.)

Por tanto, la estructura de un documento HTML queda de esta manera:

<HTML>

<HEAD>

<TITLE> Título de la página </TITLE>

</HEAD>

<BODY>

[Aquí van las etiquetas que visualizan la página]

</BODY>

1
</HTML>

2. DANDO FORMA AL TEXTO DEL DOCUMENTO HTML

Cuando escribimos en el documento el texto que queremos que aparezca en la pantalla, veremos
que éste se acomoda a ella, sin que tengamos que pulsar el retorno del carro. Si queremos separar
el texto en distintos párrafos debemos usar la etiqueta <P>, (que no tiene su correspondiente
etiqueta de cierre </P>)

El texto puede tener unas cabeceras, comprendidas entre las etiquetas <H1> y </H1>, <H2> y
</H2>, etc. (hasta el número 6), siendo el número indicativo del tamaño. El tamaño mayor es el
correspondiente al número 1.

Una etiqueta muy interesante es la de centrado <CENTER> y </CENTER> (no la soportan todos
los navegadores, aunque sí la mayoría de ellos). Nos centra todo lo que esté dentro de ella, ya sea
texto, imágenes, etc.

También tenemos los separadores (horizontal rules), que se consiguen con la etiqueta <HR> (no
existe la correspondiente de cierre). Con ella se obtiene una raya horizontal tan ancha como la
pantalla, y con la apariencia de estar embutida sobre el fondo, como se puede observar a
continuación:

<HTML>

<HEAD>

<TITLE> Mi pagina en el Web - 1 </TITLE>

</HEAD>

<BODY>

<H1> <CENTER> Primera Pagina </CENTER> </H1>

<HR>

Esta es mi primera pagina, aunque todavía es muy sencilla. Como él

lenguaje HTML no es difícil, pronto estaré en condiciones de hacer

cosas más interesantes.

<P> Aquí va un segundo párrafo, que les parece.

</BODY>

</HTML>

Una etiqueta puede estar anidada dentro de otra. En el ejemplo anterior cómo lo está la etiqueta
<CENTER> dentro de la etiqueta <H1>.

2
Cuando queremos poner un texto sin ninguna característica especial, lo ponemos directamente.
Unicamente, la separación entre párrafos (dejando una línea en blanco) la conseguimos con la
etiqueta <P>.

Si queremos separar los párrafos, o cualquier otra cosa, pero sin dejar una línea en blanco,
usamos una etiqueta parecida <BR> (break, o romper). Tampoco tiene etiqueta de cierre.

Al escribir el texto, si ponemos más de un espacio en blanco entre dos palabras observamos que el
navegador sólo reconoce uno de ellos. Si queremos forzarle a que lo haga, debemos poner el
código "&nbsp;" (non-breaking space).

Para destacar alguna parte del texto se pueden usar:

<B> y </B> para poner algo en negrita (bold).

<I> y </I> para poner algo en cursiva (italic).

Otra etiqueta interesante es <PRE> y </PRE>. El texto que se encuentre entre ella estará
preformateado, es decir que aparecerá como si hubiera sido escrito con una máquina de escribir,
con una fuente de espaciado fijo (tipo Courier). Además se respetarán los espacios en blanco y
retornos del carro, tal como estaban en nuestro documento HTML. Es muy apropiada para
confeccionar tablas y otros documentos similares.

Con la etiqueta <TT> y </TT> conseguimos también que el texto tenga un tamaño menor y la
apariencia de los caracteres de una máquina de escribir (typewriter). La diferencia con la anterior
es que no preformatea el texto, sino que únicamente cambia su apariencia.

La etiqueta <BLOCKQUOTE> y </BLOCKQUOTE> se utiliza para destacar una cita textual dentro
del texto general. Este párrafo está escrito entre ambas etiquetas. Obsérvese los márgenes a
ambos lados.

En las fórmulas matemáticas puede interesar poder escribir índices y subíndices, que se consiguen
con las etiquetas <SUP> </SUP> y <SUB> </SUB> respectivamente.

A menudo nos interesará presentar las cosas en forma de listas. Podemos escoger entre tres tipos
distintos:

o Listas desordenadas (no numeradas)


o Listas ordenadas (numeradas)
o Listas de definición.

Las listas desordenadas (Unordered Lists) sirven para presentar cosas que, por no tener un orden
determinado, no necesitan ir precedidas por un número. Su estructura es la siguiente:

<UL>

<LI> Un elemento

<LI> Otro elemento

<LI> Otro más

3
<LI> etc.

</UL>

Es decir, toda la lista está dentro de la etiqueta <UL> y </UL>, y luego cada elemento va precedida
de la etiqueta <LI> (list ítem). El resultado de lo anterior es el siguiente:

Se puede anidar una lista dentro de otra. Por ejemplo:

<UL>

<LI> Mamíferos

<LI> Peces

<UL>

<LI> Sardina

<LI> Bacalao

</UL>

<LI> Aves

</UL>

Las listas ordenadas (Ordered Lists) sirven para presentar elementos en un orden determinado. Su
estructura es muy similar a la anterior. La diferencia estriba en que en el resultado aparecerá
automáticamente un número correlativo para cada elemento.

<OL>

<LI> Primer Elemento

<LI> Segundo Elemento

<LI> Tercer Elemento

<LI> etc.

</OL>

Al igual que las listas desordenadas, también se pueden anidar las listas ordenadas.

El tercer tipo lo forman las listas de definición. Como su nombre indica, son apropiadas para
glosarios (o definiciones de términos). Toda la lista debe ir englobada entre las etiquetas <DL> y
</DL>. Y a diferencia de las dos que hemos visto, cada renglón de la lista tiene dos partes:

o El nombre de la cosa a definir , que se consigue con la etiqueta <DT> (definition


term).

4
o La definición de dicha cosa, que se consigue con la etiqueta <DD> (definition
definition).

<DL>

<DT> Una cosa a definir

<DD> La definición de esta cosa

<DT> Otra cosa a definir

<DD> La definición de esta otra cosa

</DL>

Comentarios no visibles en la pantalla

A veces es muy útil escribir comentarios en el documento HTML sobre el código que escribimos,
que nos pueden servir para recordar posteriormente sobre lo que hicimos, y que no queremos que
se vean en pantalla.

Esto se consigue encerrando dichos comentarios entre estos dos símbolos: <!-- y -->

<HTML>

<HEAD>

<TITLE> Mi pagina del Web - 2 </TITLE>

</HEAD>

<BODY>

<CENTER>

<H1> Mis aficiones </H1>

</CENTER>

<HR>

Sin un orden particular, mis <B> aficiones </B> son las siguientes:

<!-- Una lista sin orden alguno -->

<UL>

<LI> El cine

<LI> El deporte

5
<UL>

<LI> Natacion

<LI> Baloncesto

</UL>

<LI> La musica

</UL>

La musica que más me gusta es <I> (en orden de preferencia): </I>

<!-- Una lista con un orden -->

<OL>

<LI> El rock

<LI> El jazz

<LI> La musica clasica

</OL>

</BODY>

</HTML>

3. Caracteres especiales

Existen algunas limitaciones para escribir el texto. Una de ellas es debido a que las etiquetas se
forman como un comando escrito entre los símbolos "<" y ">". Por tanto, si se quisieran escribir
estos caracteres como parte normal del texto, daría esto lugar a una ambigüedad, ya que el
programa navegador podría interpretarlos como el comienzo o final de una etiqueta, en vez de un
carácter más del texto.

Para resolver este problema, existen unos códigos para poder escribir estos caracteres y otros
relacionados con las etiquetas.

&lt; para < (less than, menor que)


&gt; para > (greater than, mayor que)
&amp; para & (ampersand)
&quot; para " (double quotation)

Como se ve, estos códigos empiezan siempre con el signo "&" y acaban siempre con ";"

6
De una manera similar, existen códigos para escribir letras específicas de distintos idiomas. Hay
muchos de ellos, pero, lógicamente, los que más nos interesan son los propios del castellano (las
vocales acentuadas, la " ñ " y los signos " ¿ " y " ¡ " )

Los códigos de las vocales acentuadas se forman comenzando con " & ", seguido de la vocal en
cuestión, seguido de la palabra acute (aguda) y terminando con el signo " ; "

&aacute; Para la á
&eacute; Para la é
&iacute; Para la í
&oacute; Para la ó
&uacute; Para la ú
&Aacute; Para la Á
&Eacute; Para la É
&Iacute; Para la Í
&Oacute; Para la Ó
&Uacute; Para la Ú

El resto de los códigos son:

&ntilde; Para la ñ
&Ntilde; Para la Ñ
&uuml; Para la ü
&Uuml; Para la Ü
&#191; Para ¿
&#161; Para ¡

Todo esto, que como se ve es muy laborioso, puede parecer inútil ya que si escribimos nuestro
texto sin hacer ningún caso de estas convenciones, escribiendo las letras acentuadas y demás
signos directamente, es muy posible que el resultado lo veamos correctamente en nuestro
navegador, pero nunca podremos, estar seguros que les ocurra lo mismo a todos los que accedan
a nuestras páginas con otros navegadores distintos.

4. ENLACES

La característica que más ha influido en el espectacular éxito del WEB ha sido, aparte la de su
carácter multimedia, la posibilidad de unir los distintos documentos repartidos por todo el mundo
por medio de enlaces hipertexto.

En general, los enlaces tienen la siguiente estructura:

<A HREF="XXX"> YYY </A>

Donde XXX es el destino del enlace (Obsérvese las comillas). YYY es el texto indicativo en la
pantalla del enlace (con un color especial y generalmente subrayado)

7
Tipos de enlaces

1. Enlaces dentro de la misma página


2. Enlaces con otra página nuestra
3. Enlaces con una página fuera de nuestro sistema
4. Enlaces con una dirección de e-mail

1. Enlaces dentro de la misma página

A veces, en el caso de documentos (o páginas) muy extensos, nos puede interesar dar un salto
desde una posición a otra determinada. En este caso, lo que antes hemos llamado XXX, es decir,
el destino del enlace, en este caso el sitio dentro de la página a donde queremos saltar, se
sustituye por #MARCA (la palabra MARCA puede ser cualquier palabra que queramos). Lo que
hemos llamado antes YYY es la palabra (o palabras) que aparecerán en la pantalla en color (en
forma de hipertexto). Su estructura es, entonces:

<A HREF="#MARCA"> YYY </A>

Y en el sitio exacto a donde queremos saltar, debemos poner la siguiente etiqueta:

<A NAME="MARCA"> </A>

2. Enlaces con otra página nuestra

Puede ser que tengamos una sola página. Pero lo más frecuente es que tengamos varias páginas,
una inicial (o principal) y otras conectadas a ella, e incluso entre ellas mismas.

Supongamos que queremos enlazar con la página creada en el ejemplo 2, que la hemos llamado
mipag2.html. En este caso, simplemente sustituimos lo que hemos llamado XXX (el destino del
enlace) por el nombre del archivo:

<A HREF="mipag2.html"> Ejemplo de mi segunda pagina </A>

Si queremos que vaya a un sitio concreto de otra página nuestra en vez de ir al principio de la
página, adonde va por defecto, en ese sitio tenemos que colocar una marca (ver la Enlaces dentro
de la misma página), y completar el enlace con la referencia a esa marca.

Lo veremos con el siguiente ejemplo: <A NAME="MIMARCA"></A> es la marca que colocaremos


en nuestra pagina, que deseamos accesar desde otra nuestra. Entonces la etiqueta tiene que ser:
<A HREF="mipag2.html#MIMARCA"> En mi otra pagina </A>.

Una observación importante: Pudiera ocurrir que nuestro sitio del WEB estuviera organizado con
un directorio principal, y otros subdirectorios auxiliares. Si la página a la que deseamos accesar
está, por ejemplo en el subdirectorio misubdir, entonces en la etiqueta tendría que colocarse
"misubdir/mipag2.html".

Y a la inversa, si quiero saltar desde una página a otra que está en un directorio anterior, en la
etiqueta tendría que haber puesto "../mipag2.html". Esos dos puntos hace que se dirija al directorio
anterior. Obsérvese que se debe utilizar el símbolo / para indicar los subdirectorios, y no este otro \,
que es propio únicamente de Windows.

8
Si nos queremos evitar todas estas complicaciones, podemos tener todo junto en un único
directorio, pero esto tiene el inconveniente de que esté todo más desordenado, y sean más difíciles
de hacer las futuras modificaciones.

3. Enlaces con una página fuera de nuestro sistema

Si queremos enlazar con una página que esté fuera de nuestro sistema (es decir, que esté en un
servidor distinto al que soporta nuestra página), es necesario conocer su dirección completa, o
URL (Uniform Resource Locator). El URL podría ser, además de la dirección de una página del
WEB, una dirección de FTP, GOPHER, etc.

Una vez conocida la dirección (o URL), lo colocamos en vez de lo que hemos llamado
anteriormente XXX (el destino del enlace). Si queremos enlazar por ejemplo con la página de
Netscape (cuyo URL es: http://home.netscape.com/), la etiqueta sería:

<A HREF="http://home.netscape.com/"> Página inicial de Netscape </A>

Es muy importante copiar estas direcciones correctamente (respetando las mayúsculas y


minúsculas, pues los servidores UNIX sí las distinguen)

4. Enlaces con una dirección de e-mail

En este caso, sustituimos lo que se ha llamado antes XXX (el destino del enlace) por mailto:
seguido de la dirección de e-mail. La estructura de la etiqueta es:

<A HREF= "mailto: dirección de e-mail"> Texto del enlace </A>

Un ejemplo podría ser:

<A HREF="mailto:rodrigo@cienciasmisticas.com.ar">Webmaster</A>

Hay algunos navegadores que no subrayan el comentario de este tipo de enlace.

Una manera recomendable y más segura para conocer la dirección e-mail seria poner algo así
como:

Comentarios al webmaster en <A


HREF="mailto:rodrigo@cienciasmisticas.com.ar">
rodrigo@cienciasmisticas.com.ar </A>

Es decir, es conveniente, por la razón dicha anteriormente, poner también en el texto del enlace la
dirección de e-mail.

<HTML>

<HEAD>

<TITLE> Mi pagina del Web - 3 </TITLE>

</HEAD>

<BODY>

9
<CENTER>

<H1> Mis paginas favoritas </H1>

</CENTER>

<HR>

Estas son mis paginas favoritas:

<P><A HREF="http://home.netscape.com"> Netscape </A>

<BR> <A HREF="http://www.microsoft.com"> Microsoft </A>

<BR> <A HREF="http://www.yahoo.com"> Yahoo! </A>

</BODY>

</HTML>

5. IMAGENES

La etiqueta que nos sirve para incluir imágenes en nuestras páginas del WEB es muy similar a la
de enlaces a otras páginas, que hemos visto en el capítulo anterior. La única diferencia es que, en
lugar de indicar al programa navegador el nombre y la localización de un documento de texto
HTML para que lo cargue, se le indica el nombre y la localización de un archivo que contiene una
imagen.

La estructura de la etiqueta es:

<IMG SRC="imagen.gif">

Con el comando IMG SRC (image source, fuente de la imagen) se indica que se quiere cargar una
imagen llamada imagen.gif (o el nombre que tenga).

Dentro de la etiqueta se pueden añadir otros comandos, tal como ALT

<IMG SRC="imagen.gif" ALT="descripción">

Con el comando ALT se introduce una descripción (una palabra o una frase breve) indicativa de la
imagen. Este comando, que en principio se puede omitir, es en beneficio de los que accedan a
nuestra página con un programa navegador en forma de texto como el lynx. Ya que no son
capaces de ver la imagen, por lo menos pueden hacerse una idea sobre ella. Pero no es sólo por
esto. Hay casos, como veremos más adelante, en los que se utiliza una imagen como enlace a otra
página. Si se omitiera este comando, los que utilizan dichos navegadores no podrían de ninguna
manera acceder a esas páginas.

Con respecto a la localización del archivo de esa imagen, se puede decir aquí lo mismo que en el
capítulo anterior referente a los enlaces. Si no se indica nada especial, como en el caso que se ha
expuesto, quiere decir que el archivo imagen.gif está en el mismo directorio que el documento
HTML que estamos escribiendo. Si no es así, se siguen los mismos criterios que los indicados para
los enlaces.

10
Las imágenes deben estar guardadas en un formato de archivo especial llamado GIF. (Hay
también otro formato más avanzado JPG). Este formato GIF almacena las imágenes con un
máximo de 256 colores, en forma comprimida.

Un aspecto muy importante a tener en cuenta es el tamaño de las imágenes, pues una imagen
grande supone un archivo grande, y esto puede resultar en un tiempo excesivo de carga, con el
consiguiente riesgo de que quien esté intentando cargar nuestra página se canse de esperar, y
desista de ello.

Para elegir la posición de la imagen con respecto al texto hay distintas posibilidades. La más
sencilla es colocarla entre dos párrafos, con un titular a un lado. Los navegadores más actuales
(como el Netscape Navigator y el Microsoft Internet Explorer) permiten que el texto pueda rodear a
la imagen.

De momento nos vamos a limitar a escoger la posición del titular con respecto a la imagen. Se
puede poner arriba, en medio o abajo del lado de la imagen. Para ello se añade el comando ALIGN
a la etiqueta, de la siguiente manera:

<IMG SRC="isla.gif" ALIGN=TOP> Titular alineado arriba


<IMG SRC="isla.gif" ALIGN=MIDDLE> Titular alineado en medio
<IMG SRC="isla.gif" ALIGN=BOTTOM> Titular alineado abajo

Otra posibilidad muy interesante es la de utilizar una imagen como enlace a otra página. Para estos
casos se utilizan generalmente imágenes pequeñas (iconos), aunque se puede usar cualquier tipo
de imagen.

Según vimos en el capítulo anterior, la estructura general de un enlace es:

<A HREF="XXX"> YYY </A>

En este caso sustituimos XXX por el nombre del archivo de la página a la que queremos acceder.
Y en lugar de YYY ponemos la etiqueta completa de la imagen (que queda así englobada dentro
de la etiqueta del enlace).

Como por ejemplo (hombre.gif) para acceder al ejemplo práctico del capítulo 2 (mipag2.html):

<A HREF="mipag2.html"><IMG SRC="hombre.gif"></A>

Pulsando la imagen comprobamos cómo efectivamente enlaza con la página deseada. Obsérvese
además que la imagen está rodeada de un rectágulo del color normal en los enlaces. Si no se
desea que aparezca ese rectángulo, hay que incluir dentro de la etiqueta de la imagen el atributo
BORDER=0, es decir:

<A HREF="mipag2.html"><IMG SRC="hombre.gif" BORDER=0></A>

Posicionando el cursor sobre esta última imagen, comprobamos que actúa también como enlace
aunque carezca del rectángulo de color. Esto puede resultar más estético, pero se corre el riesgo
de que el usuario no se dé cuenta de que la imagen sirve de enlace.

También podemos utilizar una imagen para enlazar con otra imagen. Supongamos que queremos
enlazar con la imagen estaimagen.gif por medio de esta otra imagen desdeesta.gif:

11
<A HREF="estaimagen.gif"><IMG SRC="desdeesta.gif"></A>

Por ultimo, otra posibilidad es la de utilizar un texto para enlazar con una imagen. En este caso
sustituimos XXX (el destino del enlace) con el nombre del archivo de la imagen a la que queremos
acceder e YYY (lo que aparece en pantalla como el enlace) por el texto.

Por ejemplo:

<A HREF="isla.gif"> un paraíso tropical </A>

Un tipo de imágenes del que se hace abundante uso y que sirven para mejorar la presentación de
la página son los iconos, botones, barras separadoras, etc. A pesar de su tamaño o forma, son
imágenes como cualquier otra.

6. Alineación y dimensionado de imágenes

Alineación de las imágenes

Si se quieren lograr diseños fantasticos y rodear con textos los gráficos exactamente igual que en
las revistas se pueden usar los comando o atributos conjuntamente con la etiqueta <IMG SRC=
"imagen.gif">, ALIGN=. Donde quiera que se desee que aparezca una imagen basta con insertar:

<IMG SRC="/camino/imagen.gif" ALIGN=LEFT> Alinea la pagina a la izquierda


<IMG SRC="/camino/imagen.gif" ALIGN=CENTER> Alinea la pagina al centro
<IMG SRC="/camino/imagen.gif" ALIGN=RIGHT> Alinea la pagina a la derecha

Si se quiere interrumpir el proceso de rellenado del texto a los lados de la imagen, para que salte
hasta debajo de ella, es decir, dejar un espacio en blanco parcialmente, se pueden emplear las
siguientes extensiones de la etiqueta <BR>:

<BR CLEAR=LEFT> Busca el primer margen libre (clear) a la izquierda.


<BR CLEAR=RIGHT> Busca el primer margen libre a la derecha.
<BR CLEAR=ALL> Busca el primer margen libre a ambos lados.

Un ejemplo para aclarar esto:

<IMG SRC="imagen.gif" ALIGN=LEFT> Este texto esta a un lado de la imagen.

<BR> Este tambien esta a un lado de la imagen, en la linea siguiente.

<BR CLEAR=LEFT> Este otro texto, en cambio, ha buscado el primer margen


libre a la izquierda.

Dimensionando la imagen

Los programas navegadores cuando cargan un documento HTML y encuentran una etiqueta de
una imagen, interrumpen el proceso de carga y solicitan al servidor que le envíe dicha imagen,
quedando a la espera hasta que se complete el envío, repitiéndose este proceso con cada una de
las imágenes.

12
Esto es especialmente molesto cuando, como ocurre frecuentemente, en la cabecera de la página
se encuentra una imagen grande, ya que durante un tiempo relativamente largo no se verá nada en
la pantalla.

Para evitar este inconveniente existen unas extensiones de la etiqueta de la imagen <IMG
SRC="imagen.gif"> que sirven para indicar al navegador cuáles son sus dimensiones en pixels.
(Este dato lo habremos obtenido previamente de algún programa gráfico).

En este caso, el navegador actúa de una forma más favorable, ya que entonces, como conoce las
dimensiones de las imágenes les reserva un espacio en la pantalla y va colocando el texto de
forma apropiada, sin ninguna interrupción, a la vez que va rellenando esos espacios reservados a
las imágenes.

Estos comandos o atributos son WIDTH (ancho) y HEIGHT (alto).

Por ejemplo, para la imagen isla.gif situada más arriba:

<IMG SRC="imagen.gif" WIDTH=120 HEIGHT=94>

Es conveniente hacer esto con todas las imágenes, incluso con las más pequeñas (iconos,
botones, etc), para que no haya ninguna interrupción en el proceso de carga del documento.

Se puede también, si se quiere, dimensionar las imágenes con unos valores distintos a los que
realmente tienen, variando el tamaño, la anchura o la altura. Esto es muy conveniente, por ejemplo
para poner en la página un thumbnail (reproducción en pequeño de una imagen), que hace de
enlace a la imagen en su verdadero tamaño. De esta manera no recargamos demasiado una
página, y el usuario será quien decida qué imágenes desea cargar.

Para hacer que una imagen reducida sea el enlace con la imagen en su tamaño original, lo
conseguimos con:

<A HREF="imagen.gif"> <IMG SRC="imagen.gif" WIDTH=150 HEIGHT=75> </A>

También se puede conseguir esto de otra manera, más correcta aunque más laboriosa. Es la de
reducir en un programa gráfico esta imagen a 150x75, guardarla con otro nombre, y luego hacer
que la pequeña sea el enlace de la grande. Es más correcta esta otra solución porque no todos los
navegadores reconocen los comandos WIDTH y HEIGHT, incluso tampoco algunas de las
versiones más antiguas de Netscape.

7. Fondos y colores

Se puede cambiar el fondo de dos maneras distintas:

1.Con un color uniforme

2.Con una imagen

1. Fondos con un color uniforme

Se consigue añadiendo el comando BGCOLOR a la etiqueta <BODY> (situada al principio del


documento), de la siguiente manera:

13
<BODY BGCOLOR="#XXYYZZ">

XX Es un número indicativo de la cantidad de color rojo


YY Es un número indicativo de la cantidad de color verde
ZZ Es un número indicativo de la cantidad de color azul

Estos números están en numeración hexadecimal. Esta numeración se caracteriza por tener 16
dígitos (en lugar de los diez de la numeración decimal habitual). Estos dígitos son:

0123456789ABCDEF

Es decir, que en nuestro caso, el número menor es el 00 y el mayor el FF. Así, por ejemplo, el color
rojo es el #FF0000, porque tiene el máximo de rojo y cero de los otro dos colores. Los colores
primarios son:

#FF0000 Rojo
#00FF00 Verde
#0000FF Azul

Otros colores son:

#FFFFFF Blanco
#000000 Negro
#FFFF00 Amarillo

Para hacer un color más oscuro, hay que reducir el número de su componente, dejando los otros
dos invariables. Así, el rojo #FF0000 se puede hacer más oscuro con #AA0000, o aún más oscuro
con #550000.

Para hacer que un color tenga un tono más suave (más pastel), se deben variar los otros dos
colores haciéndolos más claros (número más alto), en una cantidad igual. Así, podemos convertir
el rojo en rosa con #FF7070.

Colores del texto y de los enlaces

Si no se variasen los colores habituales del texto y de los enlaces (negro y azul, respectivamente),
podría ocurrir que su lectura contra un fondo oscuro fuese muy dificultosa, o incluso imposible, si el
fondo fuese precisamente negro o azul.

Para evitar esto, se pueden escoger los colores del texto y de los enlaces, añadiendo a la etiqueta
(si se desea) los siguientes comandos:

TEXT color del texto


LINK color de los enlaces
VLINK color de los enlaces visitados
ALINK color de los enlaces activos (el que adquieren en el momento de ser pulsados)

14
Los códigos de los colores son los mismos que los que se han visto anteriormente.

La etiqueta, con todas sus posibilidades, sería:

<BODY BGCOLOR="#XXYYZZ" TEXT="#XXYYZZ" LINK="#XXYYZZ" VLINK="#XXYYZZ"


ALINK="#XXYYZZ">

El comando TEXT explicado anteriormente (que va englobado dentro de la etiqueta <BODY>)


cambia el color de la totalidad del texto de la página.

Tanto el Netscape Navigator 2, como el Microsoft Explorer soportan una etiqueta de color de la
fuente con la que se puede cambiar sólo una parte del texto:

<FONT COLOR="#XXYYZZ"> Este texto es de color XXYYZZ </FONT>

2. Fondos con una imagen

El fondo de una página puede ser también una imagen, ya sea en formato GIF o JPEG. Esta
imagen se repite por toda la página, de una manera análoga al tapiz de Windows. La estructura de
la etiqueta puede ser:

<BODY BACKGROUND="imagen.gif">
<BODY BACKGROUND="imagen.jpg">

No todos los navegadores soportan este formato.

Se pueden añadir también a esta etiqueta todos los comandos para cambiar los colores del texto y
de los enlaces, vistos anteriormente. Esto es imprescindible a veces para conseguir que el texto
sea legible, en contraste con el fondo.

Hay que prever la posibilidad de que quien acceda a nuestra página haya deshabilitado la carga
automática de imágenes, en cuyo caso tampoco cargaría la imagen que sirve como fondo y sólo
vería el fondo estándar de color gris. Esto podría ser muy perjudicial si hemos escogido unos
colores para el texto y los enlaces que no contrastan bien con ese fondo gris. La solución a este
problema es poner dentro de la etiqueta <BODY> los dos comandos BACKGROUND y BGCOLOR
(en este orden), teniendo cuidado en escoger un color uniforme de fondo parecido al de la imagen.

Por ejemplo, supongamos que queremos poner como fondo la imagen nubes.jpg. Escogemos
entonces un color de fondo azul claro, #CCFFFF. La etiqueta quedaría así:

<BODY BACKGROUND="nubes.jpg" BGCOLOR="#CCFFFF">

Esto tiene la ventaja adicional de que, incluso aunque no se deshabilite la carga automática de
imágenes, al cargar la página, lo primero que se ve es ese fondo de color uniforme, que luego es
reemplazado por el de la imagen.

8. Tablas

Las tablas pueden parecer un modo sencillo de disponer el texto en columnas o quizás de añadir
un titular a una ilustración, pero hay modos de sacar un gran partido de una característica
aparentemente sencilla. La etiqueta <TABLE> puede ser una poderosa herramienta de formato. Se
puede hacer por ejemplo, no mostrar el borde de una tabla en absoluto. Tambien se puede hacer

15
uso de la etiqueta <TABLE> para ubicar texto e imágenes con precisión, en prácticamente casi
cualquier lugar de una página.

Estructura de una tabla

Vamos a ver ordenadamente (de fuera hacia dentro) las etiquetas necesarias para confeccionar las
tablas.

<TABLE> Es la etiqueta general, que engloba a todas las


demás.
[resto de las etiquetas]

</TABLE>
<TABLE BORDER=n> Presenta los datos tabulados con un borde,
haciendo las tablas más atractivas, y el grosor
[resto de las etiquetas] es de n pixeles.

</TABLE>
<TR> Permite formar cada fila de la tabla. Hay que
repetirla tantas veces como filas queremos que
[etiquetas de las distintas celdas de la primera tenga la tabla.
fila]

</TR>
<TD> Permite formar las distintas celdas que
contendrá cada fila de la tabla. Hay que
[contenido de cada celda (imágenes, texto, etc.)] repetirlas tantas veces como celdas queramos
que tenga la fila.
</TD>
<TH> Es utilizada para colocar encabezamientos en
negrita sobre las columnas
[encabezamiento de tabla]

</TH>

<HTML>

<HEAD>

<TITLE> Página de prueba para tablas</TITLE>

</HEAD>

<BODY>

<TABLE BORDER>

<TR>

16
<TH>Columna 1</TH> <TH> Columna 2</TH> <TH> Columna 3</TH>

<TD>fila1 - c elda1</TD> <TD>fila1 - celda2</TD> <TD>fila1 - celda3</TD>

</TR>

<TR>

<TD>fila2 - celda1</TD> <TD>fila2 - celda2</TD> <TD>fila2 - celda3</TD>

</TR>

</TABLE>

<BR>[Aquí van las etiquetas que visualizan la página]

</BODY>

</HTML>

¿Qué pasa si el numero de celdas de una fila es distinto al de otra?

Pues el navegador forma el número de filas y columnas que haga falta, dejando espacios en
blanco en las filas que tengan menos celdas.

Titular de tabla

Se puede añadir un titulo a la tabla, es decir un texto situado encima de la tabla que indica cuál es
su contenido. Se consigue con la etiqueta <CAPTION> y </CAPTION>. Por ejemplo:

<CAPTION> Esta es mi primera tabla </CAPTION>

<CAPTION ALIGN=TOP>TITULO</CAPTION> Coloca él titulo sobre la tabla.


<CAPTION ALIGN=BOTTOM>TITULO</CAPTION> Coloca él titulo bajo la tabla.

Contenido de las celdas

Solo se ha puesto hasta ahora en el ejemplo, texto normal dentro de las distintas celdas. Pero se
puede poner en ellas cualquier otro elemento de los que van en un documento HTML, como
imágenes, enlaces, etc. No hay más que poner dentro de la etiqueta de la celda la etiqueta
correspondiente a una imagen, un enlace, etc.

Con una imagen

<TABLE BORDER>

<TR><TD> <IMG SRC="imagen.gif"> </TD>

</TR>

17
</TABLE>

Con un enlace

<TABLE BORDER>

<TR>

<TD><A HREF="index.html"> Mi página principal </A></TD>

</TR>

</TABLE>

Posicionamiento del contenido dentro de la celda

Normalmente, el contenido de una celda está alineado a la izquierda. Pero se puede cambiar esto
añadiendo dentro de la etiqueta de la celda los siguientes atributos:

<TD ALIGN=CENTER> Al centro </TD>


<TD ALIGN=RIGHT> A la derecha </TD>
<TH ALIGN=LEFT> Cabecera a la izquierda </TH>

El alineamiento por defecto en el sentido vertical es en el medio. También se puede cambiar,


añadiendo dentro de la etiqueta de la celda los siguientes atributos:

<TD VALIGN=TOP> Arriba </TD>


<TD VALIGN=BOTTOM> Abajo </TD>

Variando las dimensiones de la tabla

El navegador se encarga normalmente de dimensionar el tamaño total de la tabla de acuerdo con


el número de filas, de columnas, por el contenido de las celdas, espesor de los bordes, etc.

A veces nos puede convenir forzarle para que la tabla tenga unas dimensiones totales mayores
que las que le corresponden, tanto en anchura como en longitud. Esto se consigue añadiendo
dentro de la etiqueta de la tabla los atributos WIDTH y HEIGHT igual a un porcentaje de la
dimensión de la pantalla, o a una cifra que equivale al número de pixels.

Por ejemplo, si colocamos:

<TABLE WIDTH=60%>

O, por ejemplo ponemos:

<TABLE HEIGHT=200>

18
Celdas que abarcan a otras varias

A veces puede interesarnos que una celda se extienda sobre otras varias. Esto se consigue
añadiendo dentro de la etiqueta de la celda los atributos COLSPAN=número para extenderse sobre
un número determinado de columnas, o ROWSPAN=número para extenderse verticalmente sobre
un número determinado de filas.

Por ejemplo, en la primera tabla del ejemplo anterior vamos a añadir una fila con una sola celda,
que abarca a dos columnas:

<TR> <TD COLSPAN=2> Celda sobre 2 columnas </TD> <TR>

O, en la misma tabla, vamos a añadir una celda en la primera fila, pero que abarque también a la
siguiente:

<TD ROWSPAN=2> Celda junto a 2 filas </TD>

Color de fondo en las tablas

Podemos conseguir que las tablas tengan un color de fondo, siguiendo un procedimiento
totalmente análogo al empleado para que una página tenga un color de fondo uniforme (según
vimos en el capítulo 7). Para ello debemos utilizar el atributo BGCOLOR="#XXYYZZ", visto en
dicho capítulo.

Se puede conseguir:

<TABLE BORDER BGCOLOR="#XXYYZZ"> La totalidad de la tabla tendrá un color de


fondo.
[resto de las etiquetas]

</TABLE>
<TD BGCOLOR="#XXYYZZ"> Solamente una celda determinada tendrá
un color de fondo, distinto al del resto de la
[contenido de la celda] tabla.

</TD>

Imágenes de fondo en las tablas

El Explorer de Microsoft soporta la colocación de imágenes de fondo en el interior de las tablas, de


una manera análoga a como se hace en una página (según vimos en el capítulo 7). Para ello
debemos, utilizar el atributo BACKGROUND="imagen.gif" o BACKGROUND="imagen.jpg", visto en
dicho capítulo.

Si se utiliza dentro de la etiqueta <TABLE> la imagen en cuestión se multiplicará detrás de todas


las celdas.

(Con el Netscape no se verá ninguna imagen de fondo, sólo con el Explorer)

Si, por el contrario, sólo se pone este atributo dentro de la etiqueta de una celda concreta (<TD> o
<TH>), entonces la imagen de fondo se verá sólo en esa celda.

19
Separación entre las celdas de una tabla

Por defecto, la separación entre las distintas celdas de una tabla es de dos pixels. Pero se puede
variar esto con el atributo CELLSPACING, que se pone dentro de la etiqueta TABLE.

Por ejemplo, para obtener una separación de 20 pixels entre celdas ponemos:

<TABLE BORDER CELLSPACING=20>

A primera vista parece como si esto fuera lo mismo que si hubiéramos aumentado el espesor de
los bordes. Pero para comprobar que no es así, hagamos que en el caso anterior, tenga además
unos bordes de 5 de espesor:

<TABLE BORDER=5 CELLSPACING=20>

Separación entre el borde y el contenido dentro de las celdas

Por defecto, la separación entre el borde y el contenido dentro de las celdas es de un pixel. Se
puede cambiar esto con el atributo CELLPADDING, que se pone dentro de la etiqueta TABLE.

Por ejemplo, para obtener una separación de 20 pixels entre el contenido y los bordes, dentro de
cada celda:

<TABLE BORDER CELLPADDING=20>

Se puede combinar este atributo con CELLSPACING (visto en el apartado anterior).

Por ejemplo, una tabla con bordes de 5 de espesor, separación entre celdas de 15 y separación del
contenido con respecto a los bordes de las celdas de 20, lo obtendríamos con:

<TABLE BORDER=5 CELLSPACING=15 CELLPADDING=20>

9. Formularios

La manera general para que los lectores de nuestra página se puedan comunicar con nosotros es
por medio de un enlace a nuestra dirección de e-mail, con lo que recibiríamos un e-mail
convencional.

Pero puede ser que lo que necesitemos sea solamente una respuesta concreta a unas opciones
que presentaremos nosotros mismos, o un comentario del usuario, para lo que le suministraremos
un espacio en donde introducirlo.

Se puede, hacer todo esto, además de otras cosas, utilizando los formularios, con los que se
pueden confeccionar páginas que contengan los elementos necesarios para ello, tal como botones
de radio, listas de selección, cajetines de introducción de texto y de control, etc., como vamos a
ver.

Los formularios permiten que los demás nos envíen la información directamente a nosotros o bien
a nuestro servidor, en donde hemos instalado un programa que procese esta información. Por
ejemplo, vamos a suponer que queremos crear una lista de correo. Los usuarios pueden introducir
sus nombres y direcciones de e-mail y pulsar un botón de envío.

20
Esos datos los podemos recibir "en bruto" en nuestro correo, con los que confeccionaríamos
manualmente dicha lista de correo, sin necesitar ningún programa para ello. Este proceso es el que
vamos a comentar en este capítulo.

La otra posibilidad, de la que únicamente se va a hacer esta mención, es que hubiéramos instalado
en nuestro servidor un programa especial para procesar esos datos y añadirlos a la lista de correo,
y que incluso pudiera devolver automáticamente al usuario algún tipo de información. Para
conseguir esto, los formularios necesitan ejecutar programas o scripts por medio del CGI (Common
Gateway Interface). El CGI permite a los formularios ser procesados por programas escritos en
cualquier lenguaje, aunque los más usados en Internet son el Perl y el C.

El tipo de formulario que se describe a continuación podrá ser utilizado por la mayoría de los
navegadores, con la notable excepción del Explorer (incluso la versión 3.0), por lo que es
conveniente suministrar al final del formulario, como una alternativa para estos casos, un enlace de
e-mail ordinario (ver el Capítulo 4)

Estructura de un formulario

La estructura general de un formulario es:

1.Etiqueta de inicio:

<FORM ACTION="mailto:dirección_de_email" METHOD="POST"

ENCTYPE="TEXT/PLAIN">
2.Cuerpo del formulario

(Elementos para introducir los datos).


3.Botones de envío y de borrado.
4.Etiqueta de cierre </FORM>

1.Etiqueta de inicio

El atributo ACTION indica la acción que se debe efectuar y que es que los datos sean enviados por
e-mail a la dirección indicada. (Si hiciéramos uso del CGI, sería precisamente aquí donde
indicaríamos su localización en el servidor, que habitualmente es el directorio cgi-bin, para que
procese los datos).

El atributo METHOD=POST indica que los datos sean inmediatamente enviados por correo a la
dirección de e-mail, nada más púlsar el usuario el botón de envío.

Con el atributo ENCTYPE="TEXT/PLAIN" se consigue que las respuestas las recibamos como un
archivo de texto, perfectamente legible y sin codificar.

2.Cuerpo del Formulario (Elementos para introducir los datos)

Los vamos a dividir en tres clases:

1.Introducción por medio de texto


2.Introducción por medio de menús

21
3.Introducción por medio de botones

La introducción de los datos se consigue por medio de la etiqueta:

<INPUT TYPE= "XXX" NAME="YYY" VALUE= "ZZZ">

En donde:

XXX Es la palabra que indica el tipo de datos a introduccir.


YYY Es el nombre que le asignamos nosotros a la variable de introducción del dato.
ZZZ Es la palabra asociada a un elemento.

Todo esto, que de momento parece muy confuso, se aclarará al ir viendo los distintos casos.

Introducción por medio de texto

En este caso es XXX=TEXT, es decir, INPUT TYPE="TEXT". El atributo VALUE no procede en


este caso. Vamos a poner un ejemplo.

Solicitamos el apellido del usuario:

<FORM ACTION=mailto:direccion_de_e-mail METHOD="POST"


ENCTYPE="TEXT/PLAIN">

Escribe tu apellido:

<BR><INPUT TYPE="TEXT" NAME="Apellido">

</FORM>

Si el usuario introduce su apellido, p. ej. Ruiz, y pulsa el botón de envío (que veremos más
adelante), recibiremos, un e-mail suyo con el siguiente texto:

Apellido=Ruiz

La longitud de este formulario es por defecto de 20 caracteres. Se puede variar incluyendo en la


etiqueta el atributo SIZE="número". Por otra parte, sea cual sea la longitud del formulario, si no se
indica nada, el usuario puede introducir el número de caracteres que quiera. Se puede limitar esto,
incluyendo en la etiqueta el atributo MAXLENGTH="número".

En el caso que hemos visto, si hubiéramos cambiado la etiqueta correspondiente por:

<INPUT TYPE="text" NAME="Apellido" SIZE="10" MAXLENGTH="12">

También se puede hacer que el texto introducido no sea reconocible, es decir que todos los
caracteres se representen por asteriscos. Basta con cambiar en la etiqueta INPUT TYPE="TEXT"
por INPUT TYPE="PASSWORD". En el último ejemplo, si cambiamos la etiqueta correspondiente
por:

<INPUT TYPE="PASSWORD" NAME="Apellido" SIZE="10" MAXLENGTH="12">

22
Introducción por medio de texto (múltiples líneas)

Cuando el texto a introducir puede alcanzar una gran longitud, por ejemplo un comentario, es
conveniente utilizar un formulario de texto de múltiples líneas.

Esto se consigue con la etiqueta de inicio:

<TEXTAREA NAME="YYY" ROWS="número" COLS="número">

(en donde no se utiliza INPUT TYPE y donde ROWS representa el número de filas, y COLS el de
columnas).

y la de cierre:

</TEXTAREA>

Ejemplo: un formulario solicitando los comentarios del usuario:

<FORM ACTION="mailto:direccion_de_e-mail" METHOD="POST"


ENCTYPE="TEXT/PLAIN">

Introduce tus comentarios:

<BR><TEXTAREA NAME="Comentarios" ROWS="6" COLS="40">

</TEXTAREA>

</FORM>

(El salto de línea del texto introducido no se efectúa automáticamente).

Una vez que el usuario haya escrito sus comentarios dentro del formulario, y haya pulsado el botón
de envío, recibiremos un e-mail suyo con el siguiente texto:

Comentarios = mensaje escrito por el usuario

Introducción por medio de menús

Si queremos que el usuario, en vez de introducir un texto, como hemos visto en los casos
anteriores, escoja entre varias opciones que le presentamos nosotros, haremos uso de un
formulario en forma de menú.

Se consigue con la etiqueta de inicio <SELECT NAME= "YYY"> y la de cierre </SELECT>.

Las distintas opciones a escoger se consiguen con la etiqueta <OPTION>.

Ejemplo: Pedimos al usuario que elija su color preferido:

<FORM ACTION="mailto:dirección_de_e-mail" METHOD= "POST"


ENCTYPE="TEXT/PLAIN">

23
<BR>¿Cuál es tu color preferido?

<BR><SELECT NAME="ColorPreferido">

<OPTION SELECTED>

<OPTION>Rojo

<OPTION>Verde

<OPTION>Azul

<OPTION>Amarillo

</SELECT >

</FORM>

Si el usuario ha escogido, p. ej. Azul y ha pulsado el botón de envío, recibiremos un e-mail suyo
con el texto: ColorPreferido=Azul.

En el ejemplo anterior, sólo es visible en el formulario una opción. Si queremos que sean visibles
múltiples opciones a la vez, añadimos en la etiqueta los atributos MULTIPLE SIZE="número",
donde especificamos el número de opciones visibles.

Si cambiamos en el ejemplo anterior la etiqueta correspondiente por:

<SELECT NAME="ColorPreferido" MULTIPLE SIZE="2">

Introducción por medio de botones

Caja de confirmación (checkbox)

Si queremos que el usuario confirme una opción determinada, podemos hacer uso de un formulario
de confirmación, o checkbox, que se consigue con la etiqueta:

<INPUT TYPE="CHECKBOX" NAME="YYY">

Ejemplo: Solicitamos al usuario que confirme su inclusión en una lista de correo:

<FORM ACTION= "mailto:dirección_de_email" METHOD="POST"


ENCTYPE="TEXT/PLAIN">

<INPUT TYPE="checkbox" NAME="Lista">

Sí, deseo ser incluido en la lista de correo.

</FORM>

Si el usuario marca este formulario y pulsa el botón de envío, recibiremos un e-mail suyo con el
texto: Lista=On.

24
Si queremos que el formulario aparezca inicialmente como marcado (el usuario no necesitará
hacerlo), basta con añadir el atributo CHECKED dentro de la etiqueta. En el ejemplo anterior si
sustituimos la etiqueta equivalente por:

<INPUT TYPE="CHECKBOX" NAME="Lista" CHECKED>

Botones de radio

Cuando queremos que el usuario elija una única opción entre varias, podemos hace uso de los
botones de radio, que se consiguen con la etiqueta:

<INPUT TYPE= "RADIO" NAME= "YYY" VALUE= "ZZZ">

Donde YYY es el nombre que le ponemos a la variable que se trata de elegir, y ZZZ es el nombre
de cada una de las opciones en concreto.

Ejemplo: solicitamos al usuario que defina cuál es su sistema operativo preferido:

<FORM ACTION="mailto:dirección_de_email" METHOD="POST"


ENCTYPE="TEXT/PLAIN">

¿Cuál es tu sistema operativo preferido?

<BR>

<INPUT TYPE="radio" NAME="SistemaOperativo" VALUE="PC" CHECKED> PC

<INPUT TYPE="radio" NAME="SistemaOperativo" VALUE="Mac"> Mac

<INPUT TYPE="radio" NAME="SistemaOperativo" VALUE="Unix"> Unix

</FORM>

Obsérvese el atributo opcional CHECKED que se ha añadido en la primera etiqueta. Esa será la
opción que aparece marcada por defecto.

Obsérvese también que no es posible escoger más de una opción.

Si el usuario ha escogido la opción PC y pulsa el botón de envío, recibiremos un e-mail suyo con el
texto: SistemaOperativo=PC.

3.Botones de envío y de borrado

Hasta ahora, en todos los ejemplos que hemos visto, faltaba un elemento esencial en cualquier
formulario, y es el botón de envío de los datos, que se consigue con la etiqueta:

<INPUT TYPE= "submit" VALUE= "ZZZ">

En donde ZZZ es el texto que queremos que aparezca en el botón.

Vamos a añadirlo al primer ejemplo, en el que se solicitaba el apellido del usuario:

25
<FORM ACTION="mailto:dirección_de_email" METHOD="POST"
ENCTYPE="TEXT/PLAIN">

Escribe tu apellido:

<BR><INPUT TYPE="text" NAME="Apellido">

<P><INPUT TYPE="submit" VALUE="Enviar datos">

</FORM>

Otro botón interesante es el de borrado de los datos introducidos, muy conveniente en un


formulario con muchos elementos. Es muy similar al de envío, pues se consigue con la etiqueta:

<INPUT TYPE= "RESET" VALUE="ZZZ">

En donde ZZZ es el texto que queremos que aparezca en el botón.

Si añadimos al ejemplo anterior la etiqueta:

<P><INPUT TYPE="reset" VALUE="Borrar datos">

Se puede comprobar su funcionamiento, escribiendo algo en el formulario y pulsando luego el


botón de borrado.

Consideraciones finales

Hasta ahora hemos visto uno a uno los diferentes elementos que se pueden utilizar. Pero no hay
ningún inconveniente en usar, dentro del mismo formulario, distintos tipos de introducción de datos.
Al pulsar el usuario el botón de envío recibiríamos en e-mail suyo con las distintas parejas
NAME=VALUE de cada elemento, encadenadas con el símbolo &.

Haremos como ejemplo práctico un libro de visitas a nuestra página.

<HTML>

<HEAD>

<TITLE>Libro de Visitas</TITLE>

</HEAD>

<BODY>

<P><CENTER>

<H2>Libro de visitas</H2>

<P><FORM ACTION="mailto:o:dirección@deemail.com" METHOD="POST"


ENCTYPE="TEXT/PLAIN">

Tu nombre:

26
<BR><INPUT TYPE="text" NAME="Nombre">

<P>Escribe tus comentarios:

<BR><TEXTAREA NAME="Comentarios" ROWS="6" COLS="40">

</TEXTAREA>

<P><INPUT TYPE="submit" VALUE="Enviar datos">

<INPUT TYPE="reset" VALUE="Borrar datos">

</FORM>

<P>

<HR>

</BODY>

</HTML>

10. Mapas

Hemos visto anteriormente dos maneras distintas de enlazar una página con otra: por medio de un
enlace de texto o por medio de una imagen. Pero en este último caso se hacía uso de una imagen
para enlazar a una única página.

Se puede utilizar una única imagen para enlazar con varias páginas, yendo a una u otra según la
zona en donde se pulse el ratón. Este tipo de imágenes se llaman mapas.

Veremos cómo se crea un mapa partiendo de una imagen, y cómo se implementa dicho mapa con
el lenguaje HTML en nuestra página.

Hay dos tipos de mapas:

1. Mapas gestionados por el servidor


2. Mapas gestionados por el cliente

En nuestro caso, trataremos sobre los mapas gestionados por el cliente, pero cabe hacer mención
de los mapas gestionados por el servidor.

1. Mapas gestionados por el servidor

En este tipo de mapas al desplazar el cursor sobre la imagen que forma el mapa se van obteniendo
las distintas coordenadas. Cuando se pulsa el ratón en un punto determinado, el navegador envía
esas coordenadas al servidor, y éste comprueba en un archivo MAP (situado en su directorio cgi-
bin) cuál es la página que se corresponde con estas coordenadas, envía esta información al
navegador, y éste solicita a su vez al servidor que le enlace con dicha página.

27
Estos mapas, tienen una ventaja: que pueden ser utilizados por todos los navegadores, incluso por
las versiones más antiguas.

Pero tienen varios inconvenientes: No todos los servidores tienen implementado el programa CGI
necesario para que pueda funcionar un mapa de este tipo. Además hay que conocer el tipo de
servidor (NCSA, el más común, o CERN), pues el código a aplicar es distinto en un caso u otro.
Por otra parte, al requerir un trasiego de información entre el navegador y el servidor, el tiempo de
respuesta es mayor que en el otro tipo, como veremos a continuación.

2. Mapas gestionados por el cliente

Estos mapas son gestionados por el cliente (es decir, nuestro navegador) y no por el servidor,
como en el caso anterior.

En este tipo de mapas, al ir desplazando el cursor se observa que en ciertas zonas se convierte en
el símbolo normal para enlazar con otras páginas (una mano, habitualmente).

Si se pulsa en estas zonas activas (HOTSPOTS), el navegador consulta con el documento HTML
que ha recibido, y decide a qué página o dirección corresponde esa zona activa.

Es decir, no necesita enviar la información al servidor y esperar la respuesta de éste, con lo que el
proceso es más rápido que en el caso anterior, reduciéndose además el tráfico de datos y la
sobrecarga al servidor. Otras ventajas son que al pasar por una zona activa se muestra la dirección
a la que se corresponde (al contrario que en el caso anterior, en la que sólo se ven unas
coordenadas). Además, estos mapas se pueden utilizar off-line, al contrario también que en el otro
tipo, ya que no requieren la ayuda del servidor.

Pero tiene el inconveniente de que estos mapas no son implementados por todos los navegadores,
como en el caso anterior, aunque sí por la mayoría de los utilizados actualmente, desde las
versiones siguientes: Netscape 2.0, Microsoft Explorer 2.0, Mosaic 2.1, etc. Pero se puede obviar
este inconveniente suministrando enlaces alternativos para los navegadores que no implementen
este tipo de mapas.

En lo que sigue, vamos a ver exclusivamente cómo implementar este tipo de mapas, es decir,
mapas gestionados por el cliente (client-side image maps).

Confección de la imagen del mapa

Antes que nada, es necesario confeccionar la imagen que va a servir como mapa. Se hará con un
programa gráfico, y pueden utilizarse los formatos GIF o JPG.

Para crear una mapa para utilizarlo en nuestra página HTML, debemos seguir los siguientes pasos:

1. Se confecciona con un programa gráfico la imagen que nos va a servir como mapa.
Para definir un área activa rectangular, necesitamos conocer las coordenadas de su ángulo
superior izquierdo (X1,Y1) y las de su ángulo inferior derecho(X2,Y2).

Estas coordenadas las obtenemos con el programa gráfico con el que hemos confeccionado la
imagen.

Al obtener los datos necesarios (las coordenadas) podemos escribir el código HTML que convierta
esta imagen en un mapa.

28
Código HTML para definir un mapa gestionado por el cliente

En este caso, el código que debemos escribir es el siguiente:

<MAP NAME="nombre">

<AREA SHAPE="RECT" COORDS="X1,Y1,X2,Y2" HREF="paginaXX.html">

<AREA SHAPE="RECT" COORDS="W1,W1,Z2,Z2" HREF="paginaYY.html">

<AREA SHAPE="DEFAULT" NOHREF>

</MAP>

<IMG SRC="imagen.gif" USEMAP="#nombre">

Veamos ahora cada una de las etiquetas:

<MAP NAME="nombre"> Esta es la etiqueta de apertura del mapa, y en


donde se define su nombre.
<AREA SHAPE="RECT" Esta etiqueta define la primera zona activa. Se
COORDS="X1,Y1,X2,Y2" indica que su forma (SHAPE, en inglés) es
HREF="paginaXX.html"> rectangular, y que las coordenadas de su ángulo
superior izquierdo son (X1,Y1), y que las del
ángulo inferior derecho son (X2,Y2). A
continuación se indica cuál es enlace que se
desea obtener.
<AREA SHAPE="DEFAULT" NOHREF> Con esta etiqueta se define el área completa del
mapa, indicando que su forma es la que tiene
por defecto (default), o sea rectangular. Si se
quisiera que el mapa no abarcara la totalidad de
la imagen, o incluso que tuviera una forma
distinta, habría que indicarlo aquí, en lugar de la
instrucción DEFAULT, haciendo uso del mismo
tipo de instrucciones que las de las zonas
activas.
</MAP> Etiqueta de cierre del mapa.
<IMG SRC="imagen.gif" USEMAP="#nombre"> Con esta etiqueta se solicita primero al servidor
que envíe una imagen llamada imagen.gif. Con
USEMAP="#nombre" se indica que esta imagen
es el mapa definido anteriormente con ese
nombre, y que debe actuar en consecuencia a
las pulsaciones del ratón, solicitando un enlace
determinado en las zonas activas, o no haciendo
nada en el resto.

Con el atributo NOHREF, se define que el área completa de la imagen es una zona no activa,
excepto en las áreas definidas anteriormente como activas.

Enlaces alternativos de texto

29
Como se ha dicho anteriormente, no todos los navegadores implementan este tipo de mapas
gestionados por el cliente. Por ello, es necesario suministrar unos enlaces alternativos
convencionales de texto, para obviar este inconveniente.

Por ejemplo, a continuación del mapa, se pueden poner enlaces de texto, correspondientes a las
dos zonas activas (reduciendo la fuente, para hacerlo menos antiestético):

<FONT SIZE=-1>

<A HREF="paginaXX.html">Mi página XX</A> |

<A HREF="paginaYY.html">Mi página YY</A>

</FONT>

Zonas activas en forma de círculos o polígonos

Hasta ahora se han definido las zonas activas en forma de rectángulos. Pero se pueden definir
también estas zonas activas como círculos o como polígonos.

Para definir una zona activa circular es necesario conocer las coordenadas de su centro (X,Y) y la
longitud de su radio (R). Una vez sabidos estos datos, la etiqueta es como sigue:

<AREA SHAPE= "CIRCLE" COORDS="X,Y,R" HREF="dirección_de_la_página">

Para definir una zona activa poligonal hay que conocer las coordenadas de los distintos puntos
(X1,Y1), (X2,Y2), (X3,Y3), etc. Con estos datos, la etiqueta se escribe como sigue:

<AREA SHAPE="POLYGON" COORDS= "X1,Y1,X2,Y2,X3,Y3,..." HREF= "enlace">

11. Frames

Frames (en inglés, marcos o cuadros) es un procedimiento del lenguaje HTML para dividir la
pantalla en diferentes zonas, o ventanas, que pueden actuar independientemente unas de otras,
como si se trataran de páginas diferentes, pues incluso cada una de ellas pueden tener sus propias
barras deslizadoras. Los navegadores que lo implementan son el Netscape 2.0, y el Explorer 2.0
en adelante.

Una de sus características más importantes es que pulsando un enlace situado en un frame, se
puede cargar en otro frame una página determinada. Esto se utiliza frecuentemente para tener un
frame estrecho en la parte lateral (o superior) con un índice del contenido en forma de diferentes
enlaces, que, al ser pulsados cargan en la ventana principal las distintas páginas. De esta manera
se facilita la navegación entre las páginas, pues aunque se vaya pasando de unas a otras, siempre
estará a la vista el índice del conjunto.

Para comprender los distintos conceptos vamos a desarrollar un ejemplo, creando una página con
dos Frames. El de la izquierda va a servir de índice de lo que veamos en el de la derecha, y en
éste veremos inicialmente una página de presentación.

Documento de definición de los frames

30
Lo primero que tenemos que hacer es crear un documento HTML en el que definiremos cuántas
zonas va a haber, qué distribución y tamaño van a tener, y cuál va ser el contenido de cada una de
ellas.

En el ejemplo que vamos a desarrollar, la página va a tener dos frames distribuidos en columnas
(es decir, uno al lado del otro, en vez de uno encima del otro, lo que sería una distribución en filas).

Con respecto al tamaño, haremos que el primero (el del izquierda) ocupe el 20% del ancho de la
pantalla, y el otro, el 80% restante.

Y con respecto al contenido, el frame de la izquierda va a contener un documento HTML que va a


servir de índice de lo que veamos en el otro (y que vamos a llamar mi_indice.html), y el de la
derecha otro documento HTML que va a servir de página de presentación (al que llamaremos
mi_presentacion.html).

Todo lo anterior se refleja en el siguiente documento HTML:

<HTML>

<HEAD>

<TITLE>Mi primera pagina con frames</TITLE>

</HEAD>

<FRAMESET COLS="20%, 80%">

<FRAME SRC= "mi_indice.html">

<FRAME SRC= "mi_presentacion.html" NAME="principal">

</FRAMESET>

</HTML>

Obsérvese lo siguiente:

Es un documento parecido a los que conocíamos hasta ahora. La diferencia está en que en vez de
utilizar la etiqueta BODY, que sirve normalmente para delimitar lo que se va a ver en la pantalla, se
hace uso de la etiqueta FRAMESET (definir los frames).

En este caso, con la etiqueta <FRAMESET COLS="20%, 80%"> se define que va a haber dos
frames y que van a ir en columnas. Si hubiéramos querido que fueran en filas, habríamos puesto
ROWS (filas, en inglés). También se define el espacio en anchura que van a ocupar cada uno de
ellos en la pantalla. Se ha puesto como porcentajes del total, pero se podría también haber puesto
una cifra absoluta, que representaría el número de pixels a ocupar.

Ya se ha definido el número de frames, su distribución y su tamaño, pero falta por definir el


contenido de cada frame. Esto se hace con las etiquetas:

<FRAME SRC="mi_indice.html">

31
<FRAME SRC="mi_presentacion.html" NAME="principal">

Con esto se define que el contenido del primer frame (el de la izquierda) sea el documento HTML
mi_indice.html y el del segundo (el de la derecha) sea el documento HTML mipresentacion.html.

Obsérvese que en la etiqueta del segundo se ha incluido el atributo NAME="principal", pero no así
en el primero. El motivo es que se necesita dar un nombre al segundo frame, pues, como veremos
a continuación, en el documento del primer frame va a haber unos enlaces que van a ir dirigidos
hacia él. En este caso sólo tenemos dos frames, pero podría haber más, y es necesario
distinguirlos unos de otros. Y el primero no necesita nombre, pues no va a haber enlaces en el
segundo dirigidos hacia él.

A este documento le vamos a llamar mi_pagina.html, pero todavía no lo vamos a guardar, pues
falta por añadir algo que veremos más adelante.

Documentos HTML de cada frame

Necesitamos ahora confeccionar el documento HTML de cada uno de los frames. Recuérdese que
son como páginas independientes, que pueden tener cada una su propio fondo, etc., y todo lo que
queramos añadir en ellos y que hemos aprendido hasta ahora.

Documento del frame de la izquierda

Va a tener un fondo amarillo, y va a contener dos enlaces dirigidos al frame de la derecha.

<HTML>

<HEAD>

<TITLE> Indice </TITLE>

</HEAD>

<BODY BGCOLOR="#FFBB00">

<P><A HREF="mi_presentacion.html" TARGET="principal"> Presentación </A>

<P><A HREF="otra_pagina.html" TARGET="principal"> Esta es otra página


</A>

<P><IMG SRC="imagen.gif">

</BODY>

</HTML>

Dentro de las etiquetas de los enlaces podemos observar algo nuevo, y es el atributo TARGET (en
inglés: objetivo, blanco), que sirve para hacer que al ser activado el enlace no se cargue en el
propio frame, sino en otro, precisamente en el que hayamos llamado con ese nombre en el
documento de definición de los frames.

32
En nuestro caso, le hemos dado el nombre de "principal" al frame de la derecha, y es por tanto ahí
donde se van a cargar los documentos HTML.

Guardamos este documento con el nombre de mi_indice.html.

Documento del frame de la derecha

Va a tener un fondo negro, y va a contener sólamente un texto.

<HTML>

<HEAD>

<TITLE> Presentacion </TITLE>

</HEAD>

<BODY BGCOLOR="#000000" TEXT="#0000FF">

<CENTER>

<FONT SIZE=+3><STRONG>

<P>ESTA ES LA VERSION

<BR><FONT COLOR="#FF0000">CON FRAMES</FONT>

<BR>DE MI PAGINA

</STRONG>

</FONT>

</CENTER>

</BODY>

</HTML>

Guardamos este documento con el nombre de mi_presentacion.html

Alternativa para los navegadores que no soportan frames

Con lo visto anteriormente, ya tenemos las tres piezas que necesitamos:

Documento de definición de los frames


Documento del contenido del primer frame
Documento del contenido del segundo frame

33
Hay que prever el caso en que los navegadores no soportan o desconocen las etiquetas
FRAMESET y FRAME.

Para estos casos está prevista la etiqueta <NOFRAMES> y </NOFRAMES>. Se añaden al final del
documento de definición de los frames, y a se pone entre ambas lo que queremos que vean los
que acceden con un navegador que no soporta frames. Puede incluso ser el código HTML de una
página completa (lo que normalmente va entre las etiquetas <BODY> y </BODY>)

En nuestro caso, pudiéramos poner un mensaje advirtiendo de esta circunstancia, y dirigiendo al


usuario, con un enlace normal, hacia una página que hayamos definido como principal o de
presentacion para estos casos. (También podríamos no decir nada sobre frames, y colocar aquí el
código de la página de presentación)

<NOFRAMES>

Estas utilizando un navegador que no soporta frames. <P>Pulsa para


visitar mi <A HREF="presentacion.html"> página</A>.

</NOFRAMES>

<HTML>

<HEAD>

<TITLE>Mi pagina con frames</TITLE>

</HEAD>

<FRAMESET COLS="20%, 80%">

<FRAME SRC="mi_indice.html">

<FRAME SRC="mi_presentacion.html" NAME="principal">

</FRAMESET>

<NOFRAMES>

Estas utilizando un navegador que no soporta frames.

<P>Pulsa para visitar mi <A HREF="presentacion.html"> página</A>.

</NOFRAMES>

</HTML>

Ahora sí podemos guardar este documento con el nombre de mi_pagina.html.

Atributos de la etiqueta <FRAMESET>

La etiqueta FRAMESET, como hemos visto en el ejemplo, es la que define la distribución, el


número y tamaño de los frames. Tiene dos atributos: COLS (columnas) y ROWS (filas):

34
<FRAMESET COLS="XX, YY, ZZ, ..">
<FRAMESET ROWS="XX, YY, ZZ, ..">

Define la distribución de los frames en columnas o en filas, según se use uno u otro atributo.

Define el número de frames que habrá, pues, por ejemplo:

<FRAMESET COLS="XX, YY"> (habrá dos frames en columnas)


<FRAMESET COLS="XX, YY, ZZ"> (habrá tres frames en columnas)

Define el tamaño de los frames, según el valor que demos a XX, YY, ZZ.... Este valor se puede
expresar en:

Un porcentaje del ancho del pantalla (para las columnas), o del alto de la pantalla (para las filas).
Así, por ejemplo:

<FRAMESET COLS="%20, %80">

(la columna de la izquierda ocupará el 20% del ancho de la pantalla, y la de la derecha el 80%
restante)

<FRAMESET ROWS="%10, %70, %20">

(la fila superior ocupará el 10% del alto de la pantalla, la del medio el 70%, y la inferior el 20%)

Un número absoluto que representa el número de pixels que ocupará cada frame a lo ancho o a lo
alto (según sean filas o columnas). Así, por ejemplo:

<FRAMESET COLS="40, 600">

(la columna de la izquierda tendrá 40 pixels de ancho y la de la derecha 600). Pero es peligroso
utilizar sólo valores absolutos, pues el tamaño de la pantalla varía de un usuario a otro. Si se va a
usar algún valor absoluto para un frame, es mejor mezclarlo con alguno relativo, como los que
vamos a ver acontinuación, para que se ajuste el total a la pantalla del usuario

Un valor relativo que se consigue poniendo un asterisco (*), en vez de un número. Esto se
interpreta como que ese frame debe tener el espacio restante. Por ejemplo:

<FRAMESET ROWS="100,*,100">

(Habrá tres filas, la superior y la inferior de una altura fija de 100 pixels, y la del medio obtendrá el
espacio restante).

Si hay más de un frame con asterisco, ese espacio restante se dividirá por igual entre ellos.

Si hay un número antes del asterisco, ese frame obtiene esa cantidad más de espacio relativo. Así
"2*,*" daría dos tercios para el primer frame y un tercio para el otro.

Frames sin bordes

35
Si se desea que no haya un borde de separación entre los frames, se deben incluir el atributo
FRAMEBORDER=0 dentro de la etiqueta FRAMESET. No todas las versiones de los navegadores
lo implementan.

Para que también desaparezcan los huecos de separación entre frames hay que añadir otros dos
atributos (el primero es para el Explorer y el segundo para el Netscape): FRAMESPACING=0 y
BORDER=0. con lo que la etiqueta completa quedaría:

<FRAMESET FRAMEBORDER=0 FRAMESPACING=0 BORDER=0 COLS="xx, yy">

Atributos de la etiqueta <FRAME>

Esta etiqueta define las cararacterísticas de un frame concreto, no del conjunto de los frames,
como era el caso con la etiqueta <FRAMESET>. Puede tener los siguientes posibles atributos, que
van dentro de la etiqueta <FRAME>:

SRC="dirección" Esta dirección puede ser la de un documento HTML


(tal como hemos utilizado en el ejemplo), o cualquier
otro recurso del Web (o URL). Con este atributo se
indica lo que se cargará inicialmente en el frame. Si
no se le pone este atributo a la etiqueta <FRAME>,
entonces dicho frame aparecerá inicialmente vacío,
aunque tendrá las dimensiones asignadas.
NAME="nombre_de_la_ventana" Este atributo se usa para asignar un nombre a un
frame. De esta manera se podrá "dar en el blanco"
(en inglés, target) en esta página, desde un enlace
situado en otra página. Es decir, que pulsando en
otra página un enlace, se cargará precisamente en
ésta, tal como hemos visto en el ejemplo. El atributo
NAME es opcional. Por defecto, todas las ventanas
carecen de nombre. Los nombres que se escojan
deben comenzar por un carácter alfanumérico (una
letra o un número, pero no otro tipo de símbolo).
MARGINWIDTH="número" Se utiliza este atributo cuando se quiere controlar el
ancho de los márgenes dentro de un frame. El
número que se ponga representa los pixels de los
márgenes. Este atributo es opcional.
MARGINHEIGHT="número" Igual que el anterior, pero referido a los márgenes en
altura.
SCROLLING="yes|no|auto" Este atributo se utiliza para decidir si el frame tendrá
o no una barra deslizadora. Si se escoje "yes" tendrá
siempre una barra deslizadora. Si se escoje "no" no
la tendrá nunca, y si se escoje "auto", será el
navegador quien decida si la tendrá o no. Este
atributo es opcional. Su valor por defecto es "auto".
NORESIZE A este atributo no se le asigna un valor numérico,
como a los demás. Es un indicador para que la
ventana no se pueda re-dimensionar (en inglés,
resize) por parte del usuario. Es un atributo opcional.
Por defecto, todos los frames son re-dimensionables.
FRAMEBORDER="no" Este atributo elimina el borde en un frame, pero si se

36
quiere que se elimine completamente, también hay
que ponérselo al frame contiguo. Si se quiere
eliminar los bordes de todos los frames, se debe
colocar en la etiqueta FRAMESET, como hemos
visto anteriormente.

El atributo TARGET

En el ejemplo hemos visto que, como queríamos que los enlaces situados en el frame de la
izquierda surtieran efecto no en él mismo, sino en otro frame, teníamos que poner dentro de cada
enlace el atributo TARGET="principal", siendo "principal" el nombre que habíamos dado al segundo
frame, en el documento de definición de frames. Es decir, hemos utilizado este atributo de esta
manera:

TARGET="nombre_dado_a_otro_frame".

Estos nombres, que los escogemos nosotros, pueden ser cualquiera, pero con la condición que el
primer carácter sea alfanumérico (letra o número).

Pero hay unos nombres reservados (es decir, que no se pueden usar para denominar a un frame),
que hacen que este atributo efectúe unas funciones especiales. Para que cumplan su cometido, es
imprescindible escribir estas palabras reservadas (blank, self y top) en minúsculas.

TARGET="_blank". Hace que se abra una nueva copia del navegador, y el enlace activado se
carga en ella, a pantalla completa. Es decir, tendríamos dos copias del navegador (Netscape,
Explorer, etc.) funcionando a la vez.

TARGET="_self". Hace que el enlace se cargue en el propio frame.

TARGET="_top". Hace que el enlace se cargue a pantalla completa, suprimiendo todos los frames,
pero sin que se cargue una nueva copia del navegador. Este es particularmente útil. Un error muy
común es olvidarse de poner este atributo en los enlaces que están en un frame, con lo que resulta
que al ser activados, la página llamada se carga dentro del propio frame, lo cual es muy molesto si
esa página pertenece a otro sitio del WEB, y aún más grave si esa página tiene a su vez frames.
Este inconveniente se evita poniendo este atributo dentro de las etiquetas de los enlaces.

Frames anidados dentro de otros frames

Hasta ahora hemos contemplado sólo la posibilidad de tener una distribución de los frames bien en
filas o bien en columnas, (dependiendo que se utilice el atributo ROWS o COLS en la etiqueta
FRAMESET), pero no ambos a la vez.

Se pueden obtener distribuciones más complejas anidando filas dentro de una columna, o a la
inversa, columnas dentro de una fila.

Supongamos que queremos la siguiente distribución:

Un frame estrecho en horizontal en la parte superior, de lado a lado de la pantalla (altura, el 15%)

Otro frame estrecho en vertical en la parte izquierda, debajo del anterior (anchura, el 20%)

Un tercero ocupando el resto de la pantalla.

37
Vemos que, en realidad, esto equivale a la siguiente distribución:

Dos filas. La superior ocupa el 15% y la inferior el resto.

La fila inferior está a su vez dividida en dos columnas. La primera (la de la izquierda) ocupa el 20%
y la otra, el resto.

El documento de definición de las dos filas (olvidémonos de momento que la de abajo está
subdividida), sería:

<HTML>

<HEAD>

<TITLE>Pagina con dos filas</TITLE>

</HEAD>

<FRAMESET ROWS="15%, *">

<FRAME SRC="documento_fila_superior">

<FRAME SRC="documento_fila_inferior">

</FRAMESET>

</HTML>

Como la fila inferior, en realidad, son dos columnas (con una distribución del 20% y resto),
sustituimos (anidando) la etiqueta <FRAME SRC="documento_fila_inferior"> por:

<FRAMESET COLS="20%, *">

<FRAME SRC="documento_columna_izqda">

<FRAME SRC="documento_columna_dcha">

</FRAMESET>

Con lo que queda el documento definitvo así:

<HTML>

<HEAD>

<TITLE>Pagina con fila superior y dos columnas inferiores</TITLE>

</HEAD>

<FRAMESET ROWS="15%, *">

38
<FRAME SRC="documento_fila_superior">

<FRAMESET COLS="20%, *">

<FRAME SRC="documento_columna_izqda">

<FRAME SRC="documento_columna_dcha">

</FRAMESET>

</FRAMESET>

</HTML>

12. Sonidos

Una página del WEB puede tener sonidos incorporados, bien sea como un fondo sonoro que se
ejecuta automáticamente al cargar la página, o como una opción para que la active el propio
usuario.

Capacidades sonoras de los navegadores

Para poder escuchar los sonidos es necesario disponer, como es lógico, de una tarjeta de sonido
con sus correspondientes altavoces. Pero esto no es suficiente, pues no todos los programas
navegadores están capacitados en la misma medida.

Explorer de Microsoft

Es el que está mejor adaptado para el sonido, pues a partir de la versión 2.0 es capaz de
reproducir fondos sonoros sin necesidad de añadir nada, y no hay ninguna complicación con los
servidores, como ocurre con el Netscape. Además, a partir de la versión 3.0 del Explorer, es
incluso compatible con los plug-ins del Netscape.

Netscape

Las versiones anteriores a la 2.0 no son capaces de reproducir fondos sonoros que se ejecuten
automáticamente, sino que requerirá que se activen los programas auxiliares asociados a los
formatos, .WAV o .MID.

La versión 2.0 sí es capaz de reproducir un fondo sonoro, pero es necesario que tenga instalado un
plug-in llamado Crescendo.

La versión 3.0 lleva implícito el plug-in Live Audio (pero sólo la versión completa, no la reducida).
En caso afirmativo, es capaz de reproducir un fondo sonoro.

Pero a todas estas complicaciones de las distintas versiones de los navegadores de los usuarios,
hay otra más y es que el servidor donde esté alojada la página del WEB debe tener configurados
como MIME los formatos, .MID y .WAV. Si esto no es así, aunque depositemos en el servidor
nuestro documento HTLM acompañado por el correspondiente archivo de sonido, éste no se
ejecutará. En dicho caso, es necesario ponerse en contacto con los administradores del servidor
para que configuren como MIME los formatos, .MID y .WAV.

39
Este problema no existe, sin embargo para el Explorer, con el que no nos tenemos que preocupar
por este tema.

Fondo sonoro para el Microsoft Internet Explorer

Para las versiones 2.0 en adelante, se utiliza la etiqueta:

<BGSOUND SRC="archivo_de_sonido" LOOP=n>

El archivo de sonido puede estar en formato .MID o .WAV.

El atributo LOOP (en inglés, lazo) sirve para especificar el número (n) de veces que se debe
ejecutar el archivo de sonido. Si se escoge el número n=-1 o se pone LOOP=INFINITE, el sonido
se ejecutará indefinidamente. Se puede omitir este atributo, y entonces el archivo se ejecutará una
sola vez.

La etiqueta para que se ejecute el archivo sonido.mid dos veces en el Explorer es:

<BGSOUND SRC="sonido.mid" LOOP=2>

(Para poder oirlo, hay que estar utilizando el Explorer)

Fondo sonoro para el Netscape

La etiqueta básica para el Netscape es:

<EMBED SRC="archivo_de_sonido" WIDTH=XXX HEIGHT=YY>

donde WIDTH es la anchura y HEIGHT la altura de una consola que aparece, y que tiene
diferentes teclas (Play, Stop, Pausa, etc.) Respecto a las dimensiones XXX e YY estas dependerán
del plug-ins que existe para Netscape.

El archivo de sonido puede estar en formato, .MID o .WAV, pero recuérdese la advertencia hecha
anteriormente, de que estos formatos deben estar configurados como MIME por el servidor donde
esté alojada la página.

Dentro de la etiqueta se pueden añadir los siguientes atributos opcionales:

AUTOSTART="TRUE" Arranca automáticamente.


LOOP="TRUE" Se ejecuta ininterrumpidamente

Para conseguir que la consola sea invisible hay que añadirle el atributo HIDDEN="TRUE".

<EMBED SRC="sonido.mid" HIDDEN="TRUE">

Fondo sonoro combinado para el Explorer y el Netscape

Se pueden combinar los dos tipos distintos de etiquetas para conseguir que un fondo sonoro sea
escuchado por usuarios que utilicen tanto el Explorer como el Netscape (siempre que éste último
esté preparado para ello). En este caso, el Explorer ignorará la etiqueta del Netscape, y a la
inversa.

40
Las dos etiquetas necesarias para que se reproduzca un archivo de sonido ya sea en formato,
.WAV o .MID, como sonido de fondo, tanto por el Explorer como por el Netscape (lo hará una sola
vez):

<BGSOUND SRC="sonido.mid"> Para el Explorer.


<EMBED SRC= "sonido.mid" HIDDEN="TRUE"> Para el Netscape.

Como vimos anteriormente para que un archivo de sonido, .MID o .WAV se ejecute como sonido
de fondo, tanto por el Explorer como por el Netscape y que se ejecute indefinidamente, a la
etiqueta del Explorer basta con añadirle el atributo LOOP=INFINITE, como se ha visto
anteriormente. Y con respecto a la etiqueta del Netscape, teóricamente debería también bastar
añadirle el atributo LOOP="TRUE", pero curiosamente esto no es así, porque hay que poner las
dimensiones de la consola (que no se va a ver).

Las dos etiquetas quedarian de esta manera:

<BGSOUND SRC="sonido.mid" LOOP=INFINITE>

<EMBED SRC="sonido.mid" WIDTH=200 HEIGHT=55 AUTOSTART="TRUE" LOOP="TRUE"


HIDDEN="TRUE">

Activación del sonido por el propio usuario

Hemos visto cómo poner un sonido de fondo en una página. Hay otra opción, mucho más sencilla,
y es la de poner un enlace a un archivo de sonido, de tal manera, que al pulsarlo se ejecute el
archivo. (Ver la Capítulo 4, en el que se explica cómo crear enlaces).

Por ejemplo, poner un enlace a un archivo sonido.mid:

Escucha esta <A HREF= "sonido.mid">musica</A>

Al pulsar el enlace se activa, en una ventana aparte, el programa que ejecuta el sonido. Esto es
válido para todos los navegadores, incluso las versiones más antiguas, con la única condición de
que se haya configurado un programa auxiliar capaz de ejecutar archivos .MID o .WAV.

Se puede hacer el enlace con un icono.

Por ejemplo al hacer un enlace con un icono llamado snd.gif al archivo de sonido sondiowav el
enlace quedaria así:

<A HREF= "sonido.wav"><IMG SRC= "snd.gif"></A>

En el capítulo anterior creamos una versión con frames, en la que aparece inicialmente en el frame
de la derecha una página de presentación.

Se puede colocar a esta página una música de fondo, para que sea ejecutada por el Explorer y el
Netscape. Para ello debemos hacer lo siguiente:

En el documento de la derecha que llamamos como presentacion.html debemos añadir entre las
etiquetas </SRONG> y </FONT> (situadas al final), lo siguiente:

41
<BR><FONT COLOR="#FF0000">¡Escucha la música de fondo!</FONT>

<BGSOUND SRC="sonido.mid">

<EMBED SRC="sonido.mid" WIDTH=2 HEIGHT=0 AUTOSTART= "TRUE">

42
Curso de PHP
PHP es un lenguaje de programación muy fácil y poderoso. Gracias a él podemos hacer que
nuestros sitios web tengan capacidades dinámicas y funciones avanzadas. Este curso es simple y
rápido de entender, pero contiene todo lo necesario para empezar a programar en PHP.

Hola mundo

PHP es un lenguaje "de lado del servidor", lo que significa que el código se ejecuta en el server y
no el la PC del usuario, como lo haría JavaScript. El servidor, luego de interpretar el código PHP,
envía al navegador del visitante el resultado en forma de HTML. Eso significa que el navegador del
visitante no "ve" ni interpreta el código fuente en PHP sino solamente el resultado en HTML.

El programa más básico que podemos hacer en PHP es el famoso "Hola mundo":

<html>
<head>
<title>Hola mundo en PHP</title>
</head>
<body>
<?php
$texto = "Hola mundo";
echo $texto;
?>
</body>
</html>

Vemos que dentro de un documento HTML clásico, tenemos embebido el código PHP.

El código PHP siempre está delimitado por las etiquetas <?php y ?>. Es muy importante abrirlas y
cerrarlas correctamente.

Este programita tiene dos líneas. La primera que dice que $texto contiene "Hola mundo", y la
segunda que usa el comando echo, que imprime el contenido de $texto.

En PHP las variables inician con el signo pesos ($), y cada instrucción debe finalizar con un punto y
coma (;). El resultado, o sea lo que se enviará al navegador del visitante, es lo siguiente:

<html>
<head>
<title>Hola mundo en PHP</title>
</head>
<body>
Hola mundo
</body>
</html>

Instalar PHP en forma local

En casi todos los servidores de hosting, PHP viene preinstalado y operativo. Sin embargo instalarlo
en nuestra PC personal es sumamente útil para poder programar y probar nuestras webs sin tener
que subir y bajar archivos constantemente.

43
Afortunadamente existen paquetes que instalar directamente el servidor Apache, PHP y MySQL en
Windows, de forma tal que el proceso que tradicionalmente es largo, se puede hacer en segundos.
Uno de los mejores paquetes es el EasyPHP.

Luego de instalarlo y ejecutarlo, debemos indicarle al server local donde están nuestros sitios web
locales agregándos como "alias" en la opción "Administrar" > "Apache - Alias".

Lo recomendable es tener una carpeta llamada "C:\htdocs" con subcarpetas individuales para cada
proyecto. Esa carpeta debe ser agregada como alias.

Por ejemplo, si tenemos nuestra web en "C:\htdocs\miweb\index.php" y dimos de alta "C:\htdocs"


como alias, podremos acceder a los contenidos mediante la dirección local
http://127.0.0.1/htdocs/miweb/index.php

Comentarios en PHP

Los comentarios son útiles para marcar o dejar notas y así poder entender luego más fácilmente
que es cada parte del código en PHP. De esta manera el código será mucho mas sencillo de
comprender y a su vez de modificar o corregir.

Los comentarios que soporta PHP son iguales a los de C, C++ y los del shell de Unix, así podemos
usar // y /* */ para comentarios y comentarios multilínea respectivamente como haríamos en C:

<?php
echo 'Código visible';
// Código no visible
echo 'Más código visible';
/* más código no visible
en más de una línea */
?>

O también podemos usar # como en los comentarios del shell de Unix:

<?php
# Código no visible
echo 'Código visible';
?>

Variables

Como la "x" de las ecuaciones en matemática, en programación una variable es un elemento que
adquiere un determinado valor. Ese valor pueden ser números, caracteres (texto) u otras cosas
que luego veremos. En PHP todas las variables empiezan con el símbolo pesos ($).

El lenguaje PHP trata las variables en forma muy simple, no es necesario definirlas antes de
usarlas y pueden contener texto y números indistintamente. Por ejemplo:

<?php
$miVariableA = 'Un transistor tiene ';
$miVariableB = 3;
$miVariableC = ' patas';
// Imprimimos

44
echo $miVariableA.$miVariableB.$miVariableC;
?>

Como vemos, asignamos valor a una variable con el operador de igualdad (=), y concatenamos
(juntamos cadenas para forma otra) con el operador punto (.)

Se pueden usar variables de nombre variable, es decir una variable cuyo nombre puede cambiar
según el valor de otra variable:

<?php
$nombreVariable = "miVariable";
$$nombreVariable = "Hola";
// Imprimimos Hola
echo $miVariable;
?>

Definiendo variables

Definir o declarar una variable significa indicarle al interprete la existencia de una variable y sus
características. En la mayoría de los lenguajes de programación, debemos indicar al interprete que
vamos a usar una variable, su tipo (por ejemplo es numérica, de texto, etc) y su ámbito. En PHP no
es obligatorio definir las variables, pero si es necesario en casos en los cuales queremos definir,
por ejemplo, su ámbito.

Definimos una variable como global para que sea accesible desde cualquier parte de nuestro
programa PHP, sin necesidad de pasar el dato como parámetro.

<?php
global $miVariableGlobal = 'Hola';
?>

Constantes

Una constante es como una variable pero con la diferencia que una vez toma un valor este no
puede cambiar durante la ejecución del script, otra característica de las constantes es que siempre
son globales.

Las constantes se expresan sin signo de pesos ($), y se tienen que definir usando la función
define:

<?php
define ('miConstante','valor de mi constante');
echo miConstante;
?>

Constantes predefinidas

En PHP existen algunas constantes predefinida, que contienen datos del sistema, algunas de ellas
son estas:

__FILE__

45
Recoge el nombre del archivo que se está ejecutando y la ruta completa de su ubicación en el
servidor.

__LINE__

Recoge el número de línea (incluidas líneas en blanco) del archivo PHP que se está interpretando.

PHP_OS

Recoge información sobre el Sistema Operativo que utiliza el servidor en el que se está
interpretando el programa.

PHP_VERSION

Recoge la versión de PHP que está siendo utilizada por el servidor.

Ejemplo del uso de constantes predefinidas:

<?
echo "La ruta completa de este archivo es: ". __FILE__;

echo "<br>Estamos utilizando la versión: ". PHP_VERSION ." de PHP";

echo "<br>El sistema operativo que estamos corriendo es ". PHP_OS;


?>

Operadores

Los operadores son expresiones que nos permiten manipular datos, cada uno de los datos que
pasan por un operador se llama operando, y según el número de operandos de que disponga un
operador estaremos hablando de un operador unario (un operando), binario (dos operandos), etc.

Habitualmente usamos varios operadores juntos que conforman una expresión más compleja. En
este caso, igual que con las operaciones matemáticas o lógicas, tenemos que tener en cuenta la
separación en términos.

Normas de preferencia

El orden que PHP asigna a los operadores es el siguiente:

new
[
! ~ ++ -- (int) (float) (string) (array) (object) @
*/%
+-.
<< >>
< <= > >=
== != === !==
&
^
|
&&
||

46
?:
= += -= *= /= .= %= &= |= ^= <<= >>=
print
and
xor
or
,

Igual que en las operaciones matemáticas o lógicas usamos el paréntesis para agrupar y separar
términos:

<?php
$a = 1 + 4 * 2; // El resultado es 9
$b = (1+4) * 2; // el resultado es 10
?>

Tipos de operadores

PHP dispone de una gran cantidad de operadores que listaremos a continuación:

Operadores aritméricos

Son los operadores básicos, nos permiten sumar, restar, multiplicar y dividir. Se trata de
operadores binarios en todos los casos ya que requieren dos operandos.

Adición (+) devuelve la suma de los dos operandos que recibe el operador.

<?php
$a = 1 + 2; // $a vale 3
?>

Substracción (-) devuelve la diferencia entre el primer y el segundo operando.

<?php
$a = 4 - 2; // $a vale 2
?>

Multiplicación (*) devuelve el producto de los operandos.

<?php
$a = 3 * 2; // $a vale 6
?>

División (/) devuelve el cociente en valor flotante de los operandos.

<?php
$a = 10 / 2; // $a vale 5
?>

Módulo (%) devuelve el resto de dividir el primer operando entre el segundo.

47
<?php
$a = 3 % 2; // $a vale 1
?>

Operadores de asignación

Los operadores de asignación alteran el valor de una variable, el operador de asignación básico es
el (=).

<?php
$miVariable = 'suValor';
?>

Asimismo, combinando los operadores de aritmética, bit a bit o de cadenas con el operador de
asignación, conseguimos los 'operadores combinados', con los que podemos realizar una
operación de asignación conjuntamente con otra operación:

<?php
$a = 1;
$a += 1; // Sumamos y asignamos
$a = $a + 1; // Operación equivalente
?>

En este ejemplo vemos que podemos poner el operador de suma seguido del de asignación para
incrementar el valor de la variable, asimismo podríamos usar el operador de concatenación (.=), el
de multiplicación (*=).

Operadores de comparación

Los operadores de comparación son operadores en su mayoría binarios que permiten comparar
variables devolviendo un valor booleano 1 (TRUE) si se cumple la condición que expresan o 0
(FALSE) en el caso contrario.

Los operadores binarios de comparación son:

Igual (==) devuelve 1 si los operandos son iguales aunque sean de tipo distinto.

Idéntico (===) devuelve 1 si los operandos son iguales y del mismo tipo.

Diferente (!= o <>) devuelve 1 si los operandos son distintos.

No idénticos (!==) devuelve 1 si son distintos o de tipo diferente.

Menor que (<) devuelve 1 si el primer operando es mas pequeño que el segundo.

Mayor que (>) devuelve 1 si el primer operando es mas grande que el segundo.

Menor o igual que (>=) devuelve 1 si el primer operando es mas pequeño o igual que el segundo.

Mayor o igual que (>=) devuelve 1 si el primer operando es mas grande o igual que el segundo.
Estos operadores se usan mayormente como condición para las estructuras de control.

48
El operador de comparación ternario es el '?:', este operador, evalúa una condición, que puede ser
una operación de comparación binaria y si se cumple ejecuta el segundo operando, de lo contrario
ejecuta el tercero:

<?php
echo ($variable == 1) ? 'Vale 1' : 'Vale mas de uno';
?>

Este ejemplo imprime 'Vale 1' si se cumple la expresion '$variable == 1' de lo contrario imprime
'Vale mas de uno'.

Operadores incrementales

Los operadores de incremento (++) permiten aumentar en una unidad el valor de una variable
numérica, los de decremento (--) disminuyen la misma variable en una unidad. Estos operadores
son operadores unarios.

Estos operadores pueden ponerse delante del operando, en ese caso la operación devolverá el
valor una vez operado, o después, caso en el que la operación devolverá el valor antes de operar:

<?php
$variable = 2;
echo $variable++; // Imprime 2 y luego incrementa
echo ++$variable; // Incrementa y luego imprime 4
?>

Operadores lógicos

Los operadores lógicos nos permiten crear expresiones complejas para evaluar estructuras de
control, permitiendo enlazar varias operaciones de comparación con los diferentes operadores
booleanos.

Estos operadores son mayoritariamente binarios, por lo que reciben 2 operandos, dependiendo de
estos operandos (de valor 0 o 1) devolverá 0 (FALSE) o 1 (TRUE), los operadores lógicos binarios
son:

Y (&& o and) devuelve 1 si ambos operandos son 1

O (|| o or) devuelve 1 si algún operando es 1

O exclusivo (xor) devuelve 1 si solo 1 operando es 1

Un ejemplo de como funcionan estos operadores podría ser:

<?php
echo ((1 == 1)&&(2 != 2)); // Devuelve 0
?>

Existe otro operador lógico, en este caso unario, que es el operador No (!) o negación, este
operador delante de un valor binario, devuelve el valor contrario (0 si es 1 y 1 si es 0):

49
<?php
echo !((1 == 1)&&(2 != 2)); // Devuelve 1
?>

En esta expresión primero evaluaremos los paréntesis, el primero vale 1 porque se cumple, el
segundo 0 porque no se cumple, como usamos Y (&&) y no son 1 los dos vale 0, entonces lo
negamos y vale 1.

Operadores de cadena

En esta categoría encontramos el operador de concatenación (.), que une cadenas:

<?php
$texto = 'Hola ' . 'mundo';
echo $texto;
?>

A su vez, existe un operador que hemos incluido entre los operadores de asignación, que es el
operador de asignación sobre concatenación (.=), este operador concatena a una variable un valor
dado de la siguiente manera:

<?php
$texto = 'Hola ';
$texto .= 'mundo';
echo $texto;
?>

Este operador es de gran utilidad para almacenar gran cantidad de datos en una misma variable de
manera limpia, por ejemplo:

<?php
$html = "<html>\n";
$html .= "<head>\n";
$html .= "<title>Página de ejemplo</title>\n";
$html .= "</head>\n";
$html .= "<body>\n";
$html .= "Esta es una página\n";
$html .= "de ejemplo.\n";
$html .= "</body>\n";
$html .= "</html>\n";
echo $html;
?>

Hemos almacenado una página HTML en la variable $html de forma limpia para finalmente imprimir
el resultado.

Arrays

Los arrays, matrices o vectores son tablas de valores. Simplificando, son una variable que posee
varias posiciones y que puede almacenar un valor en cada una de ellas.

Cada array se identifica y se asigna mediante una variable ($nombre) seguida de un ([]) que
contiene el índice del array. Ese índice puede ser escalar (numérico) o asociativo (cadena).

50
Arrays escalares:

Los elementos de un array escalar se escriben usando la siguiente sintaxis:

<?php
$a[]=valor;
// ó
$a[x]=valor;
?>

En el primero de los casos, PHP asigna automáticamente como índice el valor siguiente al último
asignado. Si es el primero que se define, le pondrá como índice 0 (cero).

En el segundo de los casos, seremos nosotros quienes pongamos (x) el número correspondiente al
valor del índice. Si al índice ya se le hubiera asignado un valor, cambiará el valor de la variable, en
caso contrario creará un nuevo elemento del array.

Arrays asociativos

Los elementos de un array asociativo puede escribirse usando la siguiente sintaxis:

<?php
$a["indice"]=valor;
?>

En este caso, el índice será una cadena y se escribirá entre comillas.

Ejemplo del uso de arrays:

<?php
// Creamos un array $a
$a[0]="Domingo";
$a[1]="Lunes";
$a[2]="Martes";
$a[3]="Miércoles";
$a[4]="Jueves";
$a[5]="Viernes";
$a[6]="Sábado";
echo "Al pedir que imprima $a[4] escribirá el 5º elemento: ".
$a[4]."<br>";
//
// Creamos un array $b, esta vez indicar índices
// PHP empezara a contar a partir de cero
$b[]="Domingo";
$b[]="Lunes";
$b[]="Martes";
$b[]="Miércoles";
$b[]="Jueves";
$b[]="Viernes";
$b[]="Sábado";
echo "Al pedir que imprima $b[2] escribirá el 3er elemento: ".
$b[2]."<br>";
//
// Creamos un array asociativo (un nombre y un valor)

51
$c["primero"]="Domingo";
$c["segundo"]="Lunes";
$c["tercero"]="Martes";
$c["cuarto"]="Miércoles";
$c["quinto"]="Jueves";
$c["sexto"]="Viernes";
$c["septimo"]="Sábado";
echo "Al pedir que imprima $c["sexto"] escribirá: ".$c["sexto"]."<br>";
?>

Estructuras de control

Los scripts PHP no son lineales y podemos controlar la ejecución de una acción o de un
determinado bloque de acciones. PHP dispone de lo que se llama estructuras de control, que nos
permiten ejecutar o no, una o mas veces un determinado bloque de acciones. Las estructuras de
control son:

Condifcional if - else

La estructura if nos permite ejecutar un bloque de instrucciones si se cumple una determinada


condición, de lo contrario nos permite ejecutar otro bloque de acciones identificado por la sentencia
else, si el resultado de la condición es distinto de 0, se ejecutarán las acciones del if, de lo contrario
las del else:

<?php
if($var1 == 10){
echo 'La variable vale 10';
}
else {
echo 'La variable tiene otro valor';
}
?>

La condición se escribe entre paréntesis a continuación de la palabra if, y esta formada por
operaciones PHP, sobretodo por operaciones lógicas y de comparación.

Hay otra sentencia que usamos a menudo para unir mas de un condicional if, es la sentencia elseif,
que nos permite dar otras condiciones:

<?php
if($var1 == 10){
echo 'La variable vale 10';
}
elseif($var1 == 5){
echo 'La variable vale 5';
}
else {
echo 'La variable tiene otro valor';
}
?>

En este caso, si var1 es distinto de 10, evaluará si vale 5, si es así mostrará el segundo mensaje,
sino el tercero. Podemos agregar cuantas condiciones elseif necesitemos pero siempre debe cerrar
con else.

52
Bucle while

While nos permite ejecutar un bloque de instrucciones mientras se cumpla una determinada
condición, cuando deje de cumplirse, se continuará ejecutando el resto del código PHP, la
condición se cumple mientras no de resultado 0 y esta formada por operaciones PHP, sobretodo
por operaciones lógicas y de comparación.

<?php
$var1 = 0;
while($var1 < 10){
echo "\$var1 = $var1<br>";
$var1++; // Incrementamos la variable
}
?>

Este ejemplo imprime:

$var1 = 0
$var1 = 1
$var1 = 2
$var1 = 3
$var1 = 4
$var1 = 5
$var1 = 6
$var1 = 7
$var1 = 8
$var1 = 9

Hay que tener cuidado con este tipo de bucle, en el interior del bloque de acciones siempre se
debe modificar algún parámetro de la condición para que esta acabe cumpliéndose, de lo contrario
crearemos un bucle infinito.

Bucle do - while

El bucle do while es en su esencia igual al bucle while con la diferencia de que ejecuta las acciones
antes de comprobar la condición, consiguiendo que se ejecuten las acciones una vez si la
condición retorna 0 o FALSE, así, este bucle se ejecutará siempre una vez mas que while si tienen
la misma condición:

<?php
$var1 = 0;
do {
echo "\$var1 = $var1<br>";
$var1 ++;
} while ($var1 < 10);
?>

Este ejemplo imprime:

$var1 = 0
$var1 = 1
$var1 = 2
$var1 = 3
$var1 = 4

53
$var1 = 5
$var1 = 6
$var1 = 7
$var1 = 8
$var1 = 9
$var1 = 10

Aunque en el último caso no se haya cumplido la condición de ya que $var1 no seria mas pequeño
que 10.

Bucle for

El bucle for nos permite ejecutar un bloque de instrucciones un número determinado de veces. La
estructura for necesita tres variables que se indican separadas por punto y coma (;) y son:

Estado inicial que pone valor inicial a la variable de control del bucle de condición.

La condición que se evalúa en cada ciclo, mientras se cumpla se continua ejecutando el bucle.

La acción que se ejecuta al final cada bucle y modifica la variable de la condición.

Ejemplo:

<?php
for ($var1 = 0; $var1 < 10; $var1++){
echo "\$var1 = $var1";
}
?>

1) Antes de empezar el bucle se ejecutará $var1 = 0.

2) Como paso siguiente se evaluará si $var < 10 y si se cumple ejecutará las instrucciones en el
interior del bucle.

3) Al finalizar el ciclo ejecuta la acción $var1++.

Comienza el ciclo de nuevo volviendo a 2) evaluando si $var < 10, cuando finalmente no lo cumpla,
sigue con el resto del código PHP.

Bucle foreach

El bucle foreach nos permite ejecutar un bloque de instrucciones para cada elemento de un array.
Hay que indicar el identificador de la matriz, la expresión as y seguidamente la variable que
identificará el valor del elemento:

<?php
$vector = array("uno", "dos", "tres");
foreach ($vector as $valor) {
echo "Valor: $valor<br>";
}
?>

Esta expresión también nos permite trabajar con arrays con índice, en este caso trabajaremos así:

54
<?php
$vector = array(
"uno" => 1,
"dos" => 2,
"tres" => 3,
"diecisiete" => 17
);
foreach($vector as $indice => $valor) {
print "\$vector[$indice] => $valor.\n";
}
?>

Como vemos en este caso especificamos la variable que identifica el índice y la que identifica el
valor separadas por =>

Ciclo switch

Switch nos permite hacer una u otra acción dependiendo del valor de una variable.

<?php
switch ($i) {
case 1:
echo "Vale 1";
break;
case 2:
echo "Vale 2";
break;
default:
echo "Otro valor";
}
?>

Este código hará un "switch" para la variable $i, y si coincide con alguna de los valores indicados
en case procederá y seguirá con el código, sino ejecutará el código de default.

Funciones

En toda aplicación hay bloques de código que realizamos mas de una vez. Para no repetir estos
bloques de código una y otra vez, existe el concepto de función.

Para declarar una función utilizamos la expresión function seguida del nombre que queremos dar a
la función, a continuación y entre paréntesis, los argumentos que recibe la función y finalmente y
entre corchetes el código de la función en si misma.

<?php
function miFuncion ($argumento_1, $argumento_2) {
// Codigo de la funcion
}
?>

Llamando a una función

Una vez creada la función, la debemos llamar como una función prefabricada de PHP, por su
nombre pasando los argumentos que necesita.

55
<?php
miFuncion("hola", "mundo");
?>

El valor de retorno

Las funciones pueden devolver un valor al lugar donde las llamamos, esto se hace gracias a la
instrucción return seguida del valor de retorno.

<?php
function invitar($sitio,$destinatario){
return "Estimado $destinatario: Está usted invitado a visitar
$sitio";
}
echo invitar("http://www.cienciasmisticas.com.ar/","Pepe Grillo");
?>

Este ejemplo dará como resultado:

Estimado Pepe Grillo: Esta usted invitado a visitar http://www.cienciasmisticas.com.ar/

Comando mail

El comando mail de PHP nos permite enviar correos electrónicos.

La sintaxis del comando es:

<?php
mail("destinatario","asunto","cuerpo","adicional");
?>

Ejemplo:

<?php
mail("rodrigo@cienciasmisticas.com.ar","Mensaje PHP","Este es el cuerpo
del mensaje");
?>

El email puede ser de texto plano, html o mixto. Dentro del cuerpo se pueden usar los siguientes
códigos:

\n para salto de línea


\t para sangría
\r para vuelta de línea

Procesando formularios

Al enviar un formulario HTML, los datos son enviados al servidor, donde se los procesa y se realiza
una acción en función de los datos introducidos.

Existen dos métodos con los que se envían los datos:

56
GET donde los datos del formulario son enviados al servidor a través de los encabezados HTTP y
son visibles en la URL. Como los datos son visible en la URL, este método es útil para paginar.

POST donde los datos del formulario son enviados al servidor como datos de la petición. Los datos
no se ven en la URL, y por esa razón es útil para pasar gran cantidad de datos, datos personales y
passwords.

Estos datos, podemos recogerlos desde nuestra aplicación PHP utilizando los arrays
superglobales, $_GET y $_POST de manera respectiva.

De esta manera, cuando el usuario rellena un formulario con método POST:

<form method="POST">
<input type="text" name="telefono">
</form>

El servidor recibe los datos y PHP genera la variable $_POST['telefono'], que podemos mostrar por
ejemplo con un echo:

<?php
echo $_POST['telefono'];
?>

Exactamente igual pasará cuando el método especificado sea GET.

Manejo de cookies

Para usar cookies en PHP, tenemos que tener en cuenta que la cookie se envía antes de enviar la
página, es decir, que enviaremos la cookie al navegador antes de enviar ningún carácter de la
página o recibiremos un error.

La función que usaremos para enviar una cookie es setcookie, que funciona de la siguiente
manera:

<?php
setcookie (nombre,valor,fecha);
?>

Donde 'nombre', será un identificador de la cookie que contendrá el texto indicado por 'valor' y que
tendrá vigencia hasta 'fecha'.

Vamos a hacer un ejemplo que incrementara el valor de una cookie cada vez que se visite cierta
página:

<?php
$visitas = $_COOKIE["visitas"]+1;
setcookie ("visitas", $visitas, time () + 7*24*60*60);
echo "Nos has visitado $visitas veces";
?>

Vemos que accedemos al valor de la cookie 'visitas' con un array superglobal que almacena todas
las cookies de la página y le sumamos 1:

57
<?php
$visitas = $_COOKIE["visitas"]+1;
?>

Sesiones PHP

Las sesiones sirven para almacenar una serie de variables en el servidor relacionándolas (gracias
a una variable pasada por cookie o por URL) con un usuario concreto para que estén disponibles
en diferentes páginas de nuestro sitio web.

Una vez almacenada una variable de sesión, podremos leerla desde todas las páginas de nuestra
web mientras la sesión no se destruya.

Guardar una variable

El soporte para sesiones de PHP nos permite inicializar fácilmente una sesión utilizando
session_start y gracias al vector superglobal $_SESSION, podremos trabajar con sesiones como si
de cualquier otro vector se tratara:

<?php
// Inicializamos sesión
session_start();
// Guardamos una variable
$_SESSION['nombre'] = 'Carlos Fredes';
?>

La única cosa que deberemos tener en cuenta, es que si usamos cookies no podremos haber
enviado ni un solo carácter (ni siquiera un espacio) al navegador antes del session_start, el
siguiente ejemplo nos dará error por el espacio de la línea 0:

<?php
// Inicializamos sesión
session_start();
?>

Leer una variable guardada

Luego de haber guardado una sesión, podemos acceder a sus variables desde todas las páginas
PHP de nuestra web cuando sean visitadas por el mismo usuario.

Esto lo haremos simplemente inicializando la sesión y con el mismo vector $_SESSION, para ver si
existe una variable de sesión determinada, usaremos isset cómo con cualquier otra variable.:

<?phpphp
// Inicializamos sesión
session_start();
// Comprobamos si existe la variable
if ( isset ( $_SESSION['nombre'] ) ) {
// Si existe
echo $_SESSION['nombre'];
} else {
// Si no existe
echo 'Desconocido';

58
}
?>

Borrar una variable

Podemos borrar una variable de sesión usando la función unset, pero además podemos eliminar la
sesión con session_destroy:

<?phpphp
// Inicializamos sesión
session_start();
// Borramos la variable
unset ( $_SESSION['nombre'] ) {
// Borramos toda la sesión
session_destroy();
?>

59
Curso de JavaScript
JavaScript es una de las múltiples aplicaciones que han surgido para extender las capacidades del
Lenguaje HTML. JavaScript es un lenguaje script orientado a documento. No sirve para crear
programas, sinó para agregarles características a nuestra web.

Las normas para poder escribir cualquier código de JavaScript se basan en algunos puntos básicos
y que debemos cumplir siempre. Estas normas son las siguientes:

Todo el código (sentencias) esta dentro de funciones.

Las funciones se desarrollan entre las etiquetas <script> y </script>.

Las etiquetas “<script>” deben colocarse entre las etiquetas <head> y </head>.

Las etiquetas “<title>” no pueden estar colocadas entre las de “<script>”.

La llamada a la función se hace a través de un evento de un elemento del documento.

Las funciones son un conjunto de sentencias (bloque de código) que especifica al programa las
operaciones a realizar. Son útiles para evitar la repetición de líneas y modular el código. Para
trabajar con ellas hay que desarrollarlas y llamarlas cuando lo necesitemos.

SINTAXIS DEL DESARROLLO:

function nombre_funcion([var1,var2,varN])

sentencia(s);

SINTAXIS DE LA LLAMADA:

<elemento evento=nombre_funcion([val1,val2,valN]);>

nombre_funcion(valor1,valor2,valorN);

En el primero de los casos la llamada se realiza desde un elemento del documento. En el segundo
caso la llamada se realiza desde el interior de otra función que también es posible.

LA VENTANA “ALERT”

Se trata de una ventana estándar que usamos para mostrar información en pantalla. Se puede
mostrar texto, variables y texto en conjunto con variables. El diseño de la ventana ya esta definido
lo único que podemos hacer es mostrar la información una o varias líneas. Su diseño y sintaxis es:

60
SINTAXIS:

alert(“texto de la ventana”);

alert(variable);

alert(“texto”+variable);

PRIMER PROGRAMA

Ahora vamos paso a paso a construir nuestro primer programa, y así podremos ver los elementos
principales del lenguaje y su colocación dentro del documento Web. Solo debemos seguir la teoría
vista en los temas anteriores.

EJEMPLO 1: Llamada a una función desde un elemento del documento.

<html>

<head>

<script>

function hola()

alert("Hola a todos");

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body onLoad=hola();>

</body>

</html>

EJEMPLO 2: Llamada a una función desde otra.

61
<html>

<head>

<script>

function hola()

alert("Hola a todos");

rehola();

function rehola()

alert(“hola de nuevo a todos”);

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body onLoad=hola();>

</body>

</html>

EVENTOS

Un evento es un mecanismo por el cual podemos detectar las acciones que realiza el usuario y
llamar automáticamente a la función que tengamos asociada. Desde esta función realizaremos las
acciones que tengamos desarrolladas.

SINTAXIS:

<elemento nombre_evento=nombre_funcion([parametros]);>

La siguiente tabla muestra los eventos y manipuladores de JavaScript:

62
EVENTO SE PRODUCE AL..
onLoad Terminar de cargar una página o frame (entrar).
onUnLoad Descargar una página o frame (salir).
onAbort Abortar la carga de una página.
onError Producirse algún error en la carga de la página.
onMouseOver Pasar el ratón por encima de un enlace, area o frame.
onMouseOut Dejar de estar el ratón encima de un enlace, area o frame.
onMouseMove Mover el ratón por el documento.
onKeyUp Presionar una tecla.
onClick Hacer click con el ratón.
onResize Dimensionar la ventana del navegador.
onMove Mover la ventana del navegador.
onChange Modificar texto en un control de edición. Sucede al perder el foco.
onSelect Seleccionar texto en un control de edición.
onFocus Situar el foco en un control.
onBlur Perder el foco un control.
onSubmit Enviar un formulario.
onReset Inicializar un formulario.

EJEMPLO 1:

<html>

<head>

<script>

function hola(){alert("Hola a todos");}

function adios(){alert("Adios a todos");}

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body onLoad=hola(); onUnload=adios();>

</body>

</html>

EJEMPLO 2:

<html>

63
<head>

<script>

function pulsa(){alert("Autor:RICARDO AMEZUA");}

function foco(){alert("Foco en la primera Caja");}

function tecla(){alert("Pulsada tecla");}

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body>

<input type="button" value="Autor" onClick=pulsa();>

<input type="text" size=”5” onFocus=foco();>

<input type="text" size=”5” onKeyPress=tecla();>

</body>

</html>

EJEMPLO 3:

<html>

<head>

<script>

function cambio(){alert("Cambiado el tamaño");}

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body onResize=cambio();>

</body>

</html>

VARIABLES Y CONSTANTES

64
VARIABLES:

Espacio de memoria con un nombre reservado para guardar información mientras la página este
cargada. El primer paso para poder trabajar con variables es declararlas, que es lugar donde se les
da su nombre y su ámbito.

Para dar nombre a una variable debemos tener en cuenta las siguientes normas:

No pueden contener espacios.

Distingue entre mayúsculas y minúsculas.

No pueden contener acentos, puntos o cualquier signo gramatical.

No pueden comenzar con un dígito ni contener la letra “ñ”.

Nombre único y exclusivo para cada variable salvo que estén es 2 funciones distintas.

El ámbito de una variable define si la variable se podrá utilizar en cualquier parte del documento
(es global). O si solo se podrá utilizar dentro de una función determinada (es local). La declaración
de las variables globales se realiza dentro de las etiquetas “<script>” pero fuera de cualquier
función. La declaración de las variables locales se realiza dentro de la función que nos interese
usar esa variable.

La sintaxis para declarar una variable es igual en ambos casos, la única diferencia es el lugar
donde las declaramos. La siguiente línea nos muestra como hacerlo:

var nombre_variable[=valor];

El tipo de variable es asignado automáticamente por JavaScript. Depende del primer valor que se
guarde en la variable. Por tanto los tipos de variable existentes son los que mostramos en la
siguiente tabla:

TIPO VALORES
numérica Cualquier tipo numérico
boolean True o False.
String Texto o letra.

Otro aspecto importante, es la conversión de datos, que en JavaScript es automática. Transforma


los datos de todas la variables en una expresión según el tipo de la primera variable. No es muy
segura y puede acarrear muchos problemas.

EJEMPLO:

num1=”12”;

num2=10;

x=num1+num2; // daria como resultado 1210.

65
y=num2+num1; // daria como resultado 22.

Para evitar problemas en las conversiones, se pueden utilizar métodos ya implementados que
realizan la conversión de una manera más segura.

TIPO DE CONVERSION SINTAXIS


De texto a numero entero. var_numerica=parseInt(var_texto);
De texto a coma flotante (decimal) var_numerica=parseFloat(var_texto);
De numérica a texto. Es automática sin peligro.

EJEMPLO:

<html>

<head>

<script>

var global=100;

function uno()

var local_uno=1;

alert("Global " +global +” Local “ +local_uno);

dos();

function dos()

var local_dos=2;

alert("Global " +global +” Local “ +local_dos);

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body onLoad=uno();>

66
</body>

</html>

CONSTANTES (“literales”)

Los valores iniciales que se les asigna son invariables. Estos no son variables, sino expresiones
constantes. Los tipos de literales son los mismos que en las variables, según el primer dato que
almacenemos será de un tipo u otro.

TIPO VALORES
numérica Cualquier tipo numérico
boolean True o False.
String Texto o letra.

OPERADORES

JavaScript define TRES tipos de operadores: aritméticos, relacionales y lógicos. También hay
definido un operador para realizar determinadas tareas, como las asignaciones.

ASIGNACION (=)

En JavaScript se puede utilizar el operador de asignación en cualquier expresión valida. Solo con
utilizar un signo de igualdad se realiza la asignación. El operador destino (parte izquierda) debe ser
siempre una variable, mientras que en la parte derecha puede ser cualquier expresión valida. Es
posible realizar asignaciones múltiples, igualar variables entre si y a un valor.

SINTAXIS:

variable=valor;

variable=variable1;

variable=variable1=variable2=variableN=valor;

ARITMÉTICOS

Pueden aplicarse a todo tipo de expresiones. Son utilizados para realizar operaciones matemáticas
sencillas, aunque uniéndolos se puede realizar cualquier tipo de operaciones. En la siguiente tabla
se muestran todos los operadores aritméticos.

OPERADOR DESCRIPCIÓN
- Resta.
+ Suma
* Multiplica
/ Divide

67
% Resto de una división
-- Decremento en 1.
++ Incrementa en 1.
vari+=valor Incrementa el valor de vari.
vari-=valor decrementa el valor de vari.
vari*=valor Multiplica el valor de vari.

LÓGICOS Y RELACIONALES

Los operadores relacionales hacen referencia a la relación entre unos valores y otros Los lógicos
se refiere a la forma en que esas relaciones pueden conectarse entre si. Los veremos a la par por
la estrecha relación en la que trabajan.

OPERADORES RELACIONALES OPERADORES LÓGICOS


OPERADOR DESCRIPCIÓN OPERADOR DESCRIPCIÓN
< Menor que. && Y (AND)
> Mayor que. || O (OR)
<= Menor o igual. ¡! NO (NOT)
>= Mayor o igual
== Igual
¡! = Distinto

INTRODUCCIÓN DE DATOS

JavaScript permite interactuar al usuario por medio de la introducción de datos. La introducción de


datos se puede realizar por medio de la ventana prompt o utilizando controles como cajas de texto.

VENTANA PROMPT:

SINTAXIS:

vari=prompt(“Texto de la ventana”,”valor inicial caja”);

Al pulsar el botón aceptar, el contenido de la caja pasa a vari. Si se pulsa el botón cancelar, el
contenido de la caja se pierde y vari queda con valor null.

EJEMPLO:

68
<html>

<head>

<script>

function valor()

var nombre;

nombre=prompt("Introduce Nombre:","");

alert("hola "+nombre);

</script>

</head>

<body onload=valor();>

</body>

</html>

CAJA DE TEXTO:

Otro mecanismo por el cual se pueden introducir datos, es mediante las cajas de texto. Todo el
trabajo con las cajas, esta basado en funciones y métodos ya implementadas en JavaScript. Estas
son las funciones que podemos utilizar:

FUNCIÓN DESCRIPCIÓN
variable=nombre_caja.value; Guarda el contenido de la caja
nombre_caja.value=valor o variable; Muestra en la caja el valor.
nombre_caja.value=””; Limpia el contenido de la caja.
nombre_caja.sefocus(); Envía el foco a la caja.

EJEMPLO:

<html>

<head>

<script>

function muestra()

69
{

var nombre=cnombre.value;

alert("Eres "+nombre);

cnombre.value="";

cnombre.focus();

</script>

</head>

<body>

Nombre:<input type="text" name="cnombre" size="20">

<input type="button" value="Ver" onClick=muestra();>

</body>

</html>

SENTENCIAS DE CONTROL

Es la manera que tiene JavaScript de provocar que el flujo de la ejecución avance y se ramifique
en función de los cambios y estado de los datos.

IF-ELSE:

La ejecución atraviesa un conjunto de estados boolean que determinan que bloques de código se
ejecutan. Con la utilización de esta sentencia nunca se realizarán ambos bloques de código.

SINTAXIS: En caso de ser una sola sentencia por parte las llaves son opcionales.

if (expresion-booleana)

Sentencia(s);

[else]

Sentencia(s);

70
}

La cláusula else es opcional. La expresión puede ser de cualquier tipo y más de una (siempre que
se unan mediante operadores lógicos).Otra opción posible es la utilización de if anidados, es decir
unos dentro de otros compartiendo la cláusula else.

EJEMPLO 1:

<html>

<head>

<script>

function ver()

var edad=parseInt(cedad.value);

if(edad<=18)

alert("No tienes accesotener 18");

else

alert("Bienvenido a la pagina");

</script>

<title>Pagina nueva 1</title>

</head>

<body>

Edad:

<input type="text" name="cedad" size="3" onBlur=ver();>

</body>

</html>

EJEMPLO 2:

<html>

<head>

71
<script>

function ver()

var edad=parseInt(cedad.value);

if(edad<=18)

alert(“Abono Joven”);

else

if(edad>=65)

alert(“Abono 3ª Edad”);

else

alert(“Abono normal”);

</script>

<title>Pagina nueva 1</title>

</head>

<body>

Edad:

<input type="text" name="cedad" size="3" onBlur=ver();>

</body>

</html>

SWITCH:

Es una sentencia muy similar a if-else. Si los valores con los que se compara son números se pone
directamente el pero si es texto se debe encerrar entre comillas. La sintaxis de esta sentencia es:

72
SINTAXIS:

switch (expresión){

case constante1:

sentencia(s);

break;

case constante2:

sentencia(s);

break;

case constante3:

sentencia(s);

break;

case constanteN:

sentencia(s);

break;

[default:]

sentencia(s);

El valor de la expresión se compara con cada una de las constantes de la sentencia case, si
coincide alguno, se ejecuta el código que le sigue, y cuando ejecuta break sale de este bloque
hasta salir del switch. Si ninguno coincide se realiza el bloque default (opcinal), si no lo hay no se
ejecuta nada.

En el caso que varias sentencias case realicen la misma ejecución se pueden agrupar, utilizando
una sola sentencia break. Evitamos de este modo duplicar líneas de código. La sintaxis es la
siguiente:

SINTAXIS:

switch (expresión){

case constante1:

case constante5:

73
sentencia(s);

break;

case constante3:

sentencia(s);

break;

[default:]

sentencia(s);

EJEMPLO:

<html>

<head>

<script>

function espe()

var tipo=cespe.value;

switch(tipo)

case "humano":

alert("Eres un Humano");

break;

case "planta":

alert("Eres un Vegetal");

break;

case "animal":

alert("Eres del reino Animal");

break;

74
default:

alert("Especie Desconocida");

break;

</script>

</head>

<body>

ESPECIE:

<input type="text" name="cespe" size="20" onBlur=espe();>

</body>

</html>

WHILE:

Ejecuta repetidamente el mismo bloque de código hasta que se cumpla una condición de
terminación. Hay cuatro partes en todos los bucles. Inicialización, cuerpo, iteración y condición.

SINTAXIS:

[inicialización;]

while(condicion[es])

cuerpo;

[iteración;]

DO..WHILE:

Es lo mismo que en el caso anterior pero aquí como mínimo siempre se ejecutará el cuerpo del
bucle una vez, en el tipo de bucle anterior es posible que no se ejecute ni una sola vez el contenido
de este.

SINTAXIS:

75
[inicialización;]

do{

cuerpo;

[iteración;]

}while(condición);

FOR:

Realiza las mismas operaciones que en los casos anteriores pero la sintaxis es una forma
compacta. Normalmente la condición para terminar es de tipo numérico. La iteración puede ser
cualquier expresión matemática valida. Si de los 3 términos que necesita no se pone ninguno se
convierte en un bucle infinito.

SINTAXIS: En caso de ser una sola sentencia por parte las llaves son opcionales.

for (inicio;cond_fin;iteración)

sentencia(S);

EJEMPLO: El tipo de bucle puede ser cualquiera de los 3 (for, while, do..while).

<html>

<head>

<script>

function opt()

while(valor<=10)

alert("Esto sale 10 veces:"+ valor);

valor++;

76
</script>

</head>

<body>

<a href="Ejemplo.htm" onMouseOver=opt();>ir a uno</a>

</body>

</html>

Dentro de las sentencias de control se pueden incluir las sentencias de ruptura ya que van muy
ligadas a los bucles. Estas sentencias de ruptura son continue y break. A continuación vamos a ver
como actúa cada una de ellas

La sentencia continue lo que hace es ignorar las sentencias que tiene el bucle y saltar directamente
a la condición para ver si sigue siendo verdadera, si es así, sigue dentro del bucle, en caso
contrario, saldría directamente de el.

La sentencia break tiene una operatoria más drástica que la sentencia continue, en vez de saltar a
la línea de la condición para comprobar su estado, lo que hace es abandonar directamente el bucle
dándolo por terminado.

EJEMPLO 1: Comparamos la actuación de continue y break.

CONTINUE BREAK
El bucle terminara cuando muestre el 10 El bucle terminara cuando muestre el 4
<html> <head> <script> function bucle() { var <html> <head> <script> function bucle() { var
cont=1; while(cont<=10) { alert(cont); cont+ cont=1; while(cont<=10) { alert(cont); cont++;
+; if(cont==5) continue; } } </script> </head> if(cont==5) break; } } </script> </head> <body
<body onLoad=bucle();></body> </html> onLoad=bucle();></body> </html>

EJEMPLO 2:

CONTINUE CONTINUE
El bucle terminara cuando muestre el 10 El bucle terminara cuando muestre el 4
<html> <head> <script> function bucle() <html> <head> <script> function bucle() { var
{ var cont=1; while(cont<=10) { alert(cont); cont=1; while(cont<=10) { alert(cont); cont++;
cont++; if(cont==5) continue; } } </script> if(cont==5) { cont=30; continue; } } } </script>
</head> <body onLoad=bucle();> </body> </head> <body onLoad=bucle();> </body>
</html> </html>

También podríamos considerar como sentencia de ruptura (sin serlo), un tipo de ventana estándar
llamada confirm. Este tipo de ventana nos permite elegir entre 2 opciones, cada una con un valor
de retorno. Con lo que se puede llamar a las sentencias de ruptura (break, continue) según la
opción que se elija.

77
SINTAXIS:

var_boolean=confirm(“texto de la ventana”);

BOTON PULSADO VALOR DE RETORNO


ACEPTAR true
CANCELAR false

EJEMPLO 1:

<html>

<head>

<script>

function confirma()

var respuesta=confirm("Pulsa un botón");

if (respuesta==true)

alert("Has pulsado ACEPTAR");

else

alert("Has pulsado CANCELAR");

</script>

</head>

<body onLoad=confirma();>

</body>

78
</html>

EJEMPLO 2:

<html>

<head>

<script>

function salida()

var cont=1;

var paso=1;

var res;

for(cont=1;cont<=100;cont++)

alert("Paso " +cont);

if(paso==10)

paso=0;

res=confirm("¿Desea Seguir?");

if (res==false)

break;

paso++;

</script>

</head>

<body onLoad=salida();>

79
</body>

</html>

PASO DE PARÁMETROS A FUNCIONES

Es el paso de información (parámetros) a una función. Cuando se realiza la llamada hay que
indicar entre los paréntesis los valores que se van a enviar. Estos valores son recogidos por
variables locales que son declaradas dentro de los paréntesis.

El utilizar este método de trabajo, evita duplicar líneas, agrupamos el código y nos hace más
sencillo la modificación y detección de errores en el código. El modo de hacer esto es básicamente
igual que cuando trabajos con las funciones, lo único que cambia son los valores.

SINTAXIS DE LA LLAMADA:

<elemento evento=nombre_funcion(valor1,valor2,valorN);>

nombre_funcion(valor1,valor2,valorN);

SINTAXIS DEL DESARROLLO:

function nombre_funcion(var1,var2,varN)

sentencia(s);

Solo debemos tener en cuenta, que en la llamada y el desarrollo, el número de parámetros


coincida en ambos casos.

EJEMPLO 1:

<html>

<head>

<script>

function opt(valor)

if(valor==1)

alert("Vas a ir a uno");

else

80
alert("Vas a ir a dos");

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body>

<a href="Uno.htm" onMouseOver=opt(1);>ir a uno</a>

<a href="Dos.htm" onMouseOver=opt(2);>ir a dos</a>

</body>

</html>

EJEMPLO 2:

<html>

<head>

<script>

function opt(valor)

var cadena;

switch(valor){

case 1:

cadena=”uno”;

break;

case 2:

cadena=”dos”;

break;

case 3:

cadena=”tres”;

81
break;

case 4:

cadena=”cuatro”;

break;

alert(“Vinculo “ +cadena);

</script>

<title>Autor:Ricardo Amezua</title>

</head>

<body>

<a href="Uno.htm" onMouseOver=opt(1);>uno</a>

<a href="Dos.htm" onMouseOver=opt(2);>dos</a>

<a href="Tres.htm" onMouseOver=opt(3);>tres</a>

<a href="Cuatro.htm" onMouseOver=opt(4);>cuatro</a>

</body>

</html>

MATRICES (Arrays)

Una matriz es una colección de variables del mismo tipo que tiene un nombre común. A un
elemento especifico de un matriz se accede mediante su índice. Todos los arrays tienen como
primer índice el valor 0. Hay que tener muy presente NO rebasar el valor del último índice.

SINTAXIS:

var nombre_array=new Array();

INICIALIZACIÓN DE UN ELEMENTO:

nombre_array[indice]=valor;

UTILIZACIÓN DE ELEMENTOS: Casi como si se tratase de una variable normal.

nombre_array[indice];

82
EJEMPLO:

<html>

<head>

<script>

function opt()

var tabla=new Array();

tabla[0]="hola";

tabla[1]="adios";

tabla[2]="tarde";

tabla[3]="noche";

tabla[4]=tabla[0]+tabla[1];

alert(tabla[0] +"" +tabla[1]);

alert(tabla[4]);

</script>

</head>

<body>

<input type="button" value="Ver" onClick=opt();>

</body>

</html>

CONTROLES

Hasta el momento hemos visto únicamente botones, cajas de texto y enlaces como controles con
los cuales el usuario puede interactuar. Con JavaScript podemos utilizar cualquier control de un
formulario para que el usuario interactúe con ellos igual que con los anteriormente vistos,
ampliando la flexibilidad a la hora de realizar programas. Cuantos más controles podamos utilizar
mejor.

83
CONTROL MODO DE EMPLEO
Radio Botones (Radio) Igual que un botón de comando.
Casillas de verificación (checkBox) Igual que un botón de comando o un radio botón.
Cajas de Contraseña (passWord) Igual que una caja de texto.
Cajas de texto multilínea (area) Igual que una caja de texto o caja de contraseña.
Construir el elemento como siempre, añadiendo en la
etiqueta <select> el evento change. Y en cada
Listas y Listas desplegables (select)
etiqueta <option> añadir el atributo value para poder
identificar cual de los elementos ha sido elegido.

EJEMPLO 1: Radio Botones (Radio). El ordenador generará un número aleatorio comprendido


entre 1 y 3. Nosotros deberemos pulsar en el radio botón que deseemos. Si acertamos ganamos
100pts, cada fallo perderemos 50pts. Si acertamos el ordenador automáticamente generará otro
número para seguir jugando.

<html>

<head>

<script>

var banco=100;

var num_secreto=0;

function genera()

num_secreto=Math.random()*3;

num_secreto=Math.round(num_secreto);

if(num_secreto==0)

num_secreto=3;

function juego(valor)

if(num_secreto==valor)

alert("Enhorabuena");

84
banco+=100;

genera();

else

banco-=50;

caja.value=banco;

</script>

</head>

<body onload=genera();>

Apuesta:

1<input type="radio" name="R1" onClick=juego(1);>

<br>

2<input type="radio" name="R1" onClick=juego(2);>

<br>

3<input type="radio" name="R1" onClick=juego(3);>

<br>

banco:

<input type="text" name="caja" size="20" value="100">

</body>

</html>

EJEMPLO 2: Caja de contraseña (passWord). Escribiremos una palabra en una caja de


contraseña, y por cada letra que pongamos, en una caja de texto normal, iremos viendo las letras
puestas en la caja de contraseña.

<html>

85
<head>

<script>

function pasa()

var temporal;

temporal=secre.value;

caja.value=temporal;

</script>

</head>

<body>

CONTRASEÑA:

<input type="password" name="secre" size="5" onKeyUp=pasa();>

<br>

NORMAL:

<input type="text" name="caja" size="5">

</body>

</html>

EJEMPLO 3: Lista o Lista desplegable (select). Mostramos una lista desplegable o lista (el modo
de trabajo es el mismo). De la lista desplegable elegimos un destino que nos mostrará información
del destino elegido. Más adelante trabajaremos con enlaces.

<html>

<head>

<script>

function viaje()

var valor=destino.value;

86
var cadena;

switch(valor)

case "1":

cadena="Quito. Precio: 27.900";

break;

case "2":

cadena="Moscu. Precio: 17.000";

break;

case "3":

cadena="Paris. Precio: 57.900";

break;

case "4":

cadena="Roma. Precio: 17.900";

break;

alert(cadena);

</script>

</head>

<body>

<select size="1" name="destino" onChange=viaje();>

<option value="1">Quito</option>

<option value="2">Moscu</option>

<option value="3">Paris</option>

87
<option value="4">Roma</option>

</select>

</body>

</html>

EJEMPLO 4: Mismo que el anterior pero más reducido.

<html>

<head>

<script>

function viaje()

var valor=destino.value;

alert(valor);

</script>

</head>

<body>

<select size="1" name="destino" onChange=viaje();>

<option value="Quito. Precio:17.900">Quito</option>

<option value="Moscu. Precio:17.000">Moscu</option>

<option value="Paris. Precio:57.900">Paris</option>

<option value="Roma. Precio:27.900">Roma</option>

</select>

</body>

</html>

ANIMACIONES

88
La animación en JavaScript puede ser de texto, imágenes o ambas cosas interactuando. En todos
los casos para conseguirla se trabaja del mismo modo.

Lo primero que tendremos que hacer es preparar las etiquetas del texto o de la imagen dandoles
un nombre (con los mismos requisitos que las variables) por medio del atributo name en caso de
las imágenes e id en caso de texto. De esta manera podremos hacer referencia al elemento
deseado desde la función encargada de ejecutar la animación. Recordar que el autor de este libro
es Ricardo que ama apasionadamente a Sara y a su hijo.

A continuación, añadiremos el evento con la llamada a la función (si es necesario, en muchas


ocasiones se llama a la función por medio del método setTimeout que veremos en un momento).

El último cambio que afecta a las etiquetas del texto o de la imagen afecta a los estilos. Por tanto
tendremos que añadir obligatoriamente el atributo style con todos aquellos estilos que intervengan
en la animación. De entre todos los estilos que existen, podemos destacar los que hay en la
siguiente tabla.

ESTILOS
SINTAXIS DESCRIPCIÓN
style=”Position:absolute;top:pos;left:pos” Posibilita el cambio de posición.
style=”color:nombre_color” Posibilita el cambio de color.
style=”visibility:hidden o visible” Posibilita mostrar y ocultar.
Recordar que si trabajamos con varios estilos todos se incluyen dentro de un atributo style.

Una vez construida y modificada la o las etiquetas, las variaciones que sufran sus etilos o cualquier
otro de sus atributos se realizarán en la función que tengamos preparada para ello. Para todos los
cambios que realicemos la sintaxis a seguir es:

SINTAXIS:

nombre_etiqueta.style.estilo=valor;

nombre_etiqueta.atributo=valor;

Si nuestra animación avanza según un intervalo de tiempo, debemos utilizar el método


setTimeout() para establecer el intervalo de tiempo y la llamada a la función. Este método se puede
utilizar en cualquier parte del código, pero normalmente se encuentra al principio del código y
dentro de la función donde se realiza cada uno de los pasos de nuestra animación. La sintaxis del
método es (recordar respetar mayúsculas y minúsculas):

SINTAXIS:

setTimeout(“nombre_función()”,intervalo milisegundos);

EJEMPLO 1: Texto con movimiento en horizontal.

<html>

<head>

<script>

89
var horizontal=12;

setTimeout("mueve()",500);

function mueve()

horizontal+=10;

TEXTO1.style.left=horizontal;

if(horizontal>=200)

horizontal=12;

setTimeout("mueve()",500);

</script>

</head>

<body>

<p id="TEXTO1" style="position:absolute; top:16; left:12">

TEXTO

</p>

</body>

</html>

EJEMPLO 2: Texto que aparece y desaparece.

<html>

<head>

<script>

var estado=true;

setTimeout("ver()",500);

function ver()

90
{

estado=!estado;

if(estado==true)

TEXTO1.style.visibility="visible";

else

TEXTO1.style.visibility="hidden";

setTimeout("ver()",500);

</script>

</head>

<body>

<p id="TEXTO1" style="visibility:visible">TEXTO</p>

</body>

</html>

EJEMPLO 3: Imagen que cambia cuando entra y sale el ratón.

<html>

<head>

<script>

function pasa(valor)

if(valor==1)

img.src="ten1.gif"

else

img.src="ten2.gif"

91
}

</script>

</head>

<body>

<img name="img" src="ten2.gif" onMouseOver=pasa(1); onMouseOut=pasa(2);>

</body>

</html>

EJEMPLO 4: Imágenes que van cambiando solas.

<html>

<head>

<script>

var estado=true;

setTimeout("cambio()",500);

function cambio()

estado=!estado;

if(estado==true)

img.src="tenista1.gif"

else

img.src="tenista2.gif"

setTimeout("cambio()",500);

</script>

92
</head>

<body>

<img name="img" src="tenista1.gif">

</body>

</html>

EJEMPLO 5: Cambiamos la imagen según situemos el ratón en un texto o en otro.

<html>

<head>

<script>

function imag(valor)

if(valor==1)

img.src="tenista1.gif"

else

img.src="tenista2.gif"

</script>

</head>

<body>

<table border="1" width="15%">

<tr>

<td width="100%"><p onMouseOver=imag(1);>IMAGEN 1</td>

</tr>

<tr>

<td width="100%"><p onMouseOver=imag(2);>IMAGEN 2</td>

</tr>

93
</table>

<br>

<img name="img" src="tenista1.gif">

</body>

</html>

EJEMPLO 6: Cambiar la imagen por medio de un control. En este caso una lista (select). Es igual
que en el caso anterior. Lo único que cambia es el evento que gestiona la llamada a la función.

<html>

<head>

<script>

function cambio(valor)

if(valor=="imagen1")

img.src="tenista1.gif"

else

img.src="tenista2.gif"

</script>

</head>

<body>

<select size="3" name="lista" onChange=cambio(value);>

<option value="imagen1">Imagen 1</option>

<option value="imagen2">Imagen 2</option>

</select>

<br>

<img name="img" src="tenista1.gif">

94
</body>

</html>

EJEMPLO 7: Una imagen moviéndose en vertical automáticamente.

<html>

<head>

<script>

var vertical=35;

var ida=true;

setTimeout("mover()",200);

function mover()

if(vertical<=200 && ida==true)

vertical+=10;

else

vertical-=10;

ida=false;

if(vertical<=35)

ida=true;

img.style.top=vertical;

setTimeout("mover()",200);

</script>

</head>

<body>

95
<img name="img" src="pic.gif"

style="position:absolute; left:12; top:35">

</body>

</html>

EJEMPLO 8: Varias imágenes moviéndose en vertical automáticamente.

<html>

<head>

<script>

//para que cargue la imagen desde el principio

var dibujo=new Image;

dibujo.src=”pic2.gif”;

var vertical=35;

var ida=true;

var estado=true;

setTimeout("mover()",200);

function mover()

estado=!estado;

if(estado==true)

img.src="tenista1.gif"

else

img.src="tenista2.gif"

if(vertical<=200 && ida==true)

vertical+=10;

96
else

vertical-=10;

ida=false;

if(vertical<=35)

ida=true;

img.style.top=vertical;

setTimeout("mover()",200);

</script>

</head>

<body>

<img name="img" src="pic1.gif"

style="position:absolute; left:12; top:35">

</body>

</html>

OBJETOS PREDEFINIDOS

Cuando se carga un documento en el navegador, se crean automáticamente una colección de


Objetos predefinidos, útiles para describir el documento sobre el que se trabaja, la ventana del
navegador y todo tipo de elementos de las páginas web. Se agrupan en los objetos window,
document, history, navigator y screen. También hay toda una colección de objetos para utilidades
varias.

WINDOW:

Nos permite definir las característica de la ventana del navegador o de las ventanas que
construyamos nuevas. A continuación tenemos los métodos mediante los cuales podremos definir
sus características.

METODO DESCRIPCIÓN SINTAXIS


open Abrir ventanas. var=window.open(“url”,”name”,”atrbs”);

97
close Cerrar ventanas. var.close();
opener Indica si se abrio. var_boolean=var.opener SI devuelve true
closed Indica si se cerró. var_boolean=var.closed SI devuelve false
Location Enlaza con una página. var.Location=”url”;
print Imprime el documento. var.Print();
alert Abre ventanas alert. var.alert(datos);
confirm Abre ventanas confirm. var.confirm(datos);
prompt Abre ventanas prompt. var.prompt(datos,”val inici”);
status Texto en barra estado. var.status=”mensaje”;
showModalDialog Crea ventana modal. var=window.showModalDialog(“url”,”atrbs”);
La variable solo es necesaria cuando sea una ventana distinta a la del navegador.

ATRIBUTOS DE SHOWMODALDIALOG (atrbs)


ATRIBUTO ELEMENTO
dialogWidth:valor Define el ancho.
dialogHeight:valor Define el alto.
dialogTop:valor Define posición superior
dialogLeft:valor Define posición inferior.
Todos los atributos que se pongan irán dentro de las comillas y separados por un espacio entres
ellos. Todos ellos son opcionales.

ATRIBUTOS DE OPEN (atrbs)


ATRIBUTO ELEMENTO
toolbar=[yes|no] Barra de herramientas.
location=[yes|no] Barra de direcciones.
directories=[yes|no] Histórico.
channelmode==[yes|no] Barra de canales.
menubar=[yes|no] Barra de menús.
status=[yes|no] Barra de estado.
scrollbars=[yes|no] Barras de Scroll.
resizable=[yes|no] Dimensionable.
width=pixels Ancho de ventana.
height=pixels Alto de ventana.
fullscreen=[yes|no] Maximizada.
top=pixels Posición superior.
left=pixels Posición izquierda
Todos los atributos que se pongan irán dentro de las comillas y separados por un espacio entres
ellos. Todos ellos son opcionales.

98
EJEMPLO 1:

<html>

<head>

<script>

var v1;

function abre()

v1=window.open("ab.htm","v","status=yes resizable=yes);

v1.status="Ventana creada para publicidad";

status="Ventana Estandar del Navegador";

function cierra()

v1.close();

</script>

</head>

<body onload=abre();>

<input type="button" value="Cerrar" onClick=cierra();>

</body>

</html>

EJEMPLO 2:

<html>

<head>

<script>

99
var v1;

function abre()

v1=window.open("ab.htm","v","status=yes resizable=yes);

function opera(valor)

switch(valor)

case 1:

cargapagina();

break;

case 2:

print();

break;

case 3:

var modal;

modal=window.showModalDialog("ab2.htm");

break;

function cargapagina()

var cerrada=v1.closed;

100
if(cerrada==false)

v1.Location="ab2.htm";

else

alert("Error.debe estar abierta.");

</script>

</head>

<body onload=abre();>

<input type="button" value="Cargar” onClick=opera(1);>

<br>

<input type="button" value="Imprime" onClick=opera(2);>

<br>

<input type="button" value="Modal" onClick=opera(3);>

</body>

</html>

DOCUMENT:

Objeto dependiente de window, es quien contiene las propiedades para trabajar con el documento
y su contenido, es decir, la página web. Sus métodos pueden ser usados también por window. Y
estos son con los que normalmente se trabaja.

METODO DESCRIPCION SINTAXIS


write Escribe en el documento. document.write(dato);
writeln Escribe y salta de línea. document.writeln(dato);
alinkColor Color de enlace (sin usar). document.alinkColor=”color”;
linkColor Color de enlace (activo). document.linkColor=”color”;
vlinkColor Color de enlace (usado). document.vlinkColor=”color”;
bgColor Color de fondo. document.bgColor=”color”;
fgColor Color del texto. document.fgColor=”color”;
referrer Url del documento anterior. var=document.referrer;
location Url del documento actual. var=document.location;

101
lastModified Fecha modificación. var=document.lastModified;

EJEMPLO 1:

<html>

<head>

<script>

function fondo(colores){document.bgColor=colores;}

function texto(colores){document.fgColor=colores;}

</script>

</head>

<body>

COLOR DEL FONDO <br>

BLANCO<input type="radio" name="F" onClick=fondo("white");>

<br>

ROJO<input type="radio" name="F" onClick=fondo("red");>

<br>

AZUL<input type="radio" name="F" onClick=fondo("blue");>

<br>

<br>

COLOR DEL TEXTO

NEGRO<input type="radio" name="T" onClick=texto("black");>

<br>

GRIS<input type="radio" name="T" onClick=texto("gray");>

<br>

VERDE<input type="radio" name="T" onClick=texto("green");>

</body>

102
</html>

EJEMPLO 2:

<html>

<head>

<script>

var v1;

function ver()

var fecha;

var urlantes;

var urlactual;

fecha=v1.document.lastModified;

urlantes=v1.document.referrer;

urlactual=v1.document.location;

v1.document.writeln("Creada en " +fecha);

v1.document.writeln("Dirección " +urlactual);

v1.document.write("Url anterior " +urlantes);

function abre()

v1=window.open("ab.htm","v","status=yes resizable=yes);

</script>

</head>

103
<body onLoad=crea();>

<input type="button" value="Info. Pag" onClick=ver();>

</body>

</html>

HISTORY:

Objeto derivado de window, contiene todas las direcciones que se han ido visitando durante la
sesión actual. Al ser un objeto derivado de window, este también puede utilizar sus métodos. Tiene
3 métodos:

METODO DESCRIPCIÓN SINTAXIS


back() Vuelve a la página anterior. window.history.back();
forward() Nos lleva a la página siguiente. window.history.forward();
Van donde le indique el
go(valor) -1 como back. window.history.go(valor);
número. Este puede ser:
num lleva a pag X
1 como forward

EJEMPLO:

<html>

<head>

<script>

function pasa(valor)

window.history.go(valor);

</script>

</head>

<body>

<input type="button" value="Atrás" onClick=pasa(-1);>

<br>

<input type="button" value="Adenlant" onClick=pasa(1);>

104
<br>

<a href="ab.htm">ir a la paginoa AB</a>

</body>

</html>

NAVIGATOR:

Objeto que contiene la información del navegador que se esté utilizando. Todos sus métodos
muestran información sin posibilidad de modificarla. Los métodos más comunes que se utilizan
son:

MÉTODO DESCRIPCION SINTAXIS


appName Devuelve el Nombre. var=navigator.appName;
appVer Devuelve la Versión. var=navigator.appVer;
userLanguaje Código del Lenguaje. var=navigator.userLanguage;
platform Plataforma de trabajo. var=navigator.platform;
cpuClass Tipo de micro. var=navigator.cpuClass;
connectionSpeed Velocidad de conexón. var=navigator.connectionSpeed;

EJEMPLO:

<html>

<head>

<script>

function informa()

var v1;

var nombre;

var cpu;

var sistema;

v1=window.open("","v","width=300 height=150");

v1.document.bgColor="gray";

105
nombre=navigator.appName;

cpu=navigator.cpuClass;

sistema=navigator.platform;

v1.document.writeln("Navegador: " +nombre);

v1.document.writeln("Sistema: " +sistema);

v1.document.write("Micro: " +cpu);

</script>

</head>

<body>

<input type="button" value="Info." onClick=informa();>

</body>

</html>

SCREEN:

Objeto por el cual podemos conocer la configuración y tipo de tarjeta gráfica que tiene el usuario.
Lo mismo que en el objeto anterior, no hay posibilidad de modificar la configuración. Sus métodos
más importantes son:

MÉTODO DESCRIPCIÓN SINTAXIS


height Altura de la pantalla. var=screen.height
width Ancho de la pantalla. var=screen.width
colorDepth Bits por pixel, los colores en pantalla. var=screen.colorDepth

EJEMPLO:

<html>

<head>

<script>

function resol()

106
var ancho=screen.width;

var alto=screen.height;

if(ancho<1800 && alto<1600)

alert("Aumentar Resolución a 1800x1600");

document.write("Aumente la Resolución");

</script>

</head>

<body onLoad=resol();>

</body>

</html>

MÉTODOS PARA FECHA Y HORA

Métodos que nos van a permitir realizar una serie de operaciones o procedimientos utilizando
fechas y horas. Lo primero que tendremos que hacer, construir un objeto Date, para que
posteriormente podamos utilizar los métodos de fecha y hora.

SINTAXIS DEL OBJETO:

var nombre_objeto=new Date();

MÉTODOS DE FECHA Y HORA


MÉTODO DESCRIPCIÓN
objeto.toGMTString();
objeto.getDate();
objeto.getMonth()+1;
objeto.getYear();
objeto.getHours();
objeto.getMinutes();
objeto.getSeconds();

107
Todas estas funciones tienen su pareja que nos permite modificar sus valores. Su sintaxis es la
misma, solo que ahora comienzan por set. Por ejemplo setMinutes(minutos) cambiará los minutos de
la hora del sistema.

EJEMPLO 1:

<html>

<head>

<script>

function fecha()

var obj_fecha=new Date();

var completo=obj_fecha.toGMTString();

var hora=obj_fecha.getHours();

var minuto=obj_fecha.getMinutes();

var segundo=obj_fecha.getSeconds();

var dia=obj_fecha.getDate();

var mes=obj_fecha.getMonth()+1;

var anis=obj_fecha.getYear();

alert(hora +":" +minuto +":" +segundo);

alert(dia +"/" +mes +"/" +anis);

alert(completo);

</script>

</head>

108
<body onLoad=fecha();>

</body>

</html>

EJEMPLO 2: Creación de un reloj digital.

<html>

<head>

<script>

setTimeout("reloj()",100);

function reloj()

var tiempo=new Date();

var hora=tiempo.getHours();

var minuto=tiempo.getMinutes();

var segundo=tiempo.getSeconds();

var textohora=hora+":"+minuto+":"+segundo;

caja.value=textohora;

setTimeout("reloj()",500);

</script>

</head>

<body>

<input type="text" name="caja" size="10">

</body>

<html>

MÉTODOS MATEMÁTICAS

109
Contiene los métodos para realizar cualquier tipo de operación matemática compleja. Solo
necesitamos llamar al método deseado utilizando el objeto Math (ya esta creado). Los métodos
mas útiles son:

MÉTODOS MATEMÁTICOS
MÉTODO DESCRIPCIÓN
var=Math.sin(valor); Seno de un ángulo. Expresado en radianes.
var=Math.cos(valor); Coseno de un ángulo. Expresado en radianes.
var=Math.tan(valor); Tangente de un ángulo. Expresado en radianes.
asin(),acos(),atan() Iguales a las anteriores pero devuelve arcos.
var=Math.abs(valor); Valor absoluto (su positivo).
var=Math.log(valor); Logaritmo decimal de valor.
var=Math.max(val1,val2); Devuelve el mayor de los dos.
var=Math.min(val1,val2); Devuelve el menor de los dos.
var=Math.pow(base,expon); Potencia de base
var=Math.sqrt(valor); Raíz cuadrada del valor.
var=Math.round(valor); Redondea un valor con decimales.
var=Math.random()*interv; Número aleatorio entre 0 y el intervalo.

EJEMPLO 1:

<html>

<head>

<script>

function opera(valor)

var resultado;

var num1=parseInt(cnum1.value);

var num2=parseInt(cnum2.value);

switch(valor)

case 1:

resultado=Math.sqrt(Math.abs(num1));

break;

110
case 2:

resultado=Math.pow(num1,num2);

break;

case 3:

resultado=Math.max(num1,num2);

break;

resul.value=resultado;

</script>

</head>

<body>

NUM1:

<input type="text" name="cnum1" size="5" value="0">

<br>

NUM2:

<input type="text" name="cnum2" size="5" value="0">

<br>

<br>

<input type="button" value="Raiz" onClick=opera(1);>

<input type="button" value="Potencia" onClick=opera(2);>

<input type="button" value="Máximo" onClick=opera(3);>

<br>

<br>

Resultado:<input type="text" name="resul" size="17">

</body>

111
</html>

EJEMPLO 2: Creamos números aleatorios entre 1 y 10 para luego intentar acertarlo.

<html>

<head>

<script>

var secreto;

function genera()

secreto=Math.random()*10;

secreto=Math.round(secreto);

if(secreto==0)

secreto=10;

function juego()

var numero=parseInt(caja.value);

if(numero==secreto)

alert("Muy bien.A por otro");

genera();

else

if(numero<secreto)

112
alert("Es mayor");

else

alert("es menor");

caja.focus();

caja.value="";

</script>

</head>

<body onLoad=genera();>

NUMERO:<input type="text" name="caja" size="3">

<input type="button" value="Compara" onClick=juego();>

</body>

</html>

MÉTODOS PARA CADENAS

Métodos destinados a realizar operaciones con cadenas de texto. Al igual que las funciones
matemáticas vamos a necesitar un objeto. En este caso el objeto puede ser una variable normal y
corriente que va a contener texto o también podríamos construir un objeto String. En ambos casos
se trabajará del mismo modo.

SINTAXIS DEL OBJETO String:

var nombre_objeto=new String();

MÉTODO DESCRIPCIÓN
objeto/var.length; Devuelve la longitud de la cadena.
objeto/var.charAt(indice); Devuelve la letra que este en la posición del índice.
objeto/var.subString(ind1,ind2); Devuelve el texto comprendido entre los índices.
objeto/var.indexof(letra); Devuelve el índice de la letra buscada.
objeto/var.replace(letr1,letr2); Reemplaza letr1 por letr2.
objeto/var.toLowerCase(); Transforma en minúsculas el texto del objeto.
objeto/var.toUpperCase(); Transforma en mayúsculas el texto del objeto.

113
EJEMPLO: Pedimos una contraseña de mínimo 4 letras, la pasamos a mayúsculas y mostramos la
primera letra. Si la contraseña no llega a 4 letras le avisamos del mínimo de letras y volvemos a
pedir.

<html>

<head>

<script>

function pasa()

var contra=T.value;

var nletras=contra.length;

if(nletras<4)

alert("Mínimo 4 letras");

T.value="";

nletras=0;

if(nletras!=0)

contra=contra.toUpperCase();

alert("La primera es: "+contra.charAt(0));

</script>

</head>

<body>

<input type="password" name="T" size="9" onBlur=pasa();>

</body>

114
</html>

115
Curso de ASP
Crear una página ASP

Un archivo de páginas Active Server (ASP) es un archivo de texto con la extensión .asp que
contiene cualquier combinación de lo siguiente:

• Texto
• Etiquetas HTML
• Secuencias de comandos del servidor

Un método rápido para crear un archivo .asp consiste en cambiar la extensión de los archivos
HTML (.html o .htm) por la extensión .asp. Si el archivo no contiene funciones ASP, el servidor
prescinde del proceso de secuencias de comandos ASP y envía el archivo al cliente. Como
desarrollador Web, esta opción proporciona una gran flexibilidad, ya que puede asignar a los
archivos la extensión .asp incluso si no piensa agregar funciones ASP hasta más adelante.

Para publicar el archivo .asp en Web, guarde el nuevo archivo en un directorio virtual de su sitio
Web (asegúrese de que el directorio tenga los permisos Secuencia de comandos o Ejecución). A
continuación, escriba en el explorador la dirección URL del archivo para pedirlo. (Recuerde, las
páginas ASP debe enviarlas el servidor, por lo que no puede pedirlas mediante su ruta física.)
Cuando el archivo se cargue en el explorador, observará que el servidor envió una página HTML.
Al principio puede parecer extraño, pero recuerde que el servidor analiza y ejecuta todas las
secuencias de comandos ASP del servidor antes de enviar el archivo. El usuario siempre recibe
código HTML estándar.

Para crear archivos .asp, se puede utilizar cualquier editor de textos. A medida que avance, puede
que encuentre más productivo utilizar un editor más orientado a ASP, como Microsoft(r) Visual
InterDev™. (Para obtener más información, visite el sitio Web de Microsoft Visual InterDev en la
dirección http://msdn.microsoft.com/vinterdev/.)

Agregar secuencias de comandos del servidor

Una secuencia de comandos del servidor es una serie de instrucciones que se utiliza para enviar al
servidor Web comandos de forma secuencial. (Si ya desarrolló antes sitios Web, probablemente
conozca las secuencias de comandos del cliente, que se ejecutan en el explorador Web.) En los
archivos .asp, las secuencias de comandos se separan del texto y de las etiquetas HTML mediante
delimitadores. Un delimitador es un carácter o una secuencia de caracteres que marca el principio
o el final de una unidad. En el caso de HTML, dichos delimitadores son los símbolos menor que (<)
y mayor que (>), que enmarcan las etiquetas HTML.

ASP utiliza los delimitadores <% y %> para enmarcar los comandos. Dentro de los delimitadores
puede incluir cualquier comando válido dentro del lenguaje de secuencia de comandos que esté
utilizando. El ejemplo siguiente muestra una página HTML sencilla que contiene un comando de
secuencia de comandos:

<HTML>

<BODY>

Esta página se actualizó por última vez el <%= Now ()%>.

116
</BODY>

</HTML>

La función Now() de VBScript devuelve la fecha y la hora actuales. Cuando el servidor Web
procesa esta página, reemplaza <%= Now ()%> con la fecha y la hora actuales, y devuelve la
página al explorador con el siguiente resultado:

Esta página se actualizó el 1/29/99 2:20:00 p.m.

A los comandos enmarcados por delimitadores se les llama comandos principales de secuencias
de comandos, que se procesan mediante el lenguaje principal de secuencia de comandos. Todos
los comandos utilizados dentro de los delimitadores de secuencias de comandos deben ser válidos
en el lenguaje principal de secuencia de comandos. De forma predeterminada, el lenguaje principal
de secuencia de comandos es VBScript, pero también puede establecer un lenguaje diferente.
Consulte Trabajar con lenguajes de secuencias de comandos.

Si ya conoce las secuencias de comandos del cliente, ya sabrá que la etiqueta HTML <SCRIPT>
se utiliza para delimitar las secuencias de comandos y las expresiones. También puede utilizar la
etiqueta <SCRIPT> para las secuencias de comandos del cliente, siempre que necesite definir
procedimientos en múltiples lenguajes en un archivo .asp. Para obtener más información, consulte
Trabajar con lenguajes de secuencias de comandos.

Combinar HTML y comandos de secuencias de comandos

Dentro de los delimitadores de ASP puede incluir cualquier instrucción, expresión, procedimiento u
operador que sea válido en el lenguaje principal para secuencia de comandos. Una instrucción, en
VBScript y en otros lenguajes, es una unidad sintácticamente completa que expresa un tipo de
acción, declaración o definición. La instrucción condicional If...Then...Else que aparece a
continuación es una instrucción de VBScript muy común:

<%

Dim dtmHour

dtmHour = Hour(Now())

If dtmHour < 12 Then

Saludos = "Buenos días"

Else

strGreeting = "Hola"

End If

%>

<%= strGreeting %>

117
Según la hora, la secuencia de comandos asigna el valor "Buenos días" o el valor "Hola" a la
variable de cadena strGreeting. La instrucción <%= strGreeting %> envía al explorador el valor
actual de la variable.

De esta forma, los usuarios que vean esta secuencia de comandos antes de las 12:00 de la
mañana (según la zona horaria del servidor Web) verían la siguiente línea de texto:

Buenos días

Los usuarios que vean esta secuencia de comandos después de las 12:00 de la mañana verían la
siguiente línea de texto:

Hola

Puede incluir texto HTML entre las secciones de una instrucción. Por ejemplo, la secuencia de
comandos siguiente, que combina HTML dentro de una instrucción If...Then...Else, produce el
mismo resultado que la del ejemplo anterior:

<%

Dim dtmHour

dtmHour = Hour(Now())

If dtmHour < 12 Then

%>

Buenos días

<% Else %>

Hola

<%End If %>

Si la condición es verdadera, es decir, si es antes del mediodía, el servidor Web envía al


explorador el código HTML que sigue a la condición ("Buenos días"); de lo contrario, envía el
código HTML que sigue a Else ("Hola"). Esta forma de combinar HTML y comandos de secuencia
de comandos es cómoda para continuar la instrucción If...Then...Else en varias líneas de texto
HTML. El ejemplo anterior es más útil si desea presentar un saludo en varias partes de una página
Web. Puede asignar el valor de la variable una única vez y después presentarla varias veces.

En lugar de mezclar texto HTML con comandos de secuencia de comandos, puede devolver texto
HTML al explorador desde dentro de los comandos de secuencia de comandos. Para devolver
texto al explorador, utilice el objeto integrado Response de ASP. El ejemplo siguiente produce el
mismo resultado que las secuencias de comandos anteriores:

<%

Dim dtmHour

118
dtmHour = Hour(Now())

If dtmHour < 12 Then

Response.Write "Buenos días"

Else

Response.Write "Hola"

End If

%>

Response.Write envía al explorador el texto que le sigue. Utilice Response.Write desde una
instrucción cuando desee generar de forma dinámica el texto devuelto al explorador. Por ejemplo,
puede generar una cadena de texto que contenga los valores de varias variables. Aprenderá más
acerca del objeto Response, y de los objetos en general, en Utilizar componentes y objetos y
Enviar contenido al explorador. Por ahora, observe simplemente que dispone de varias maneras de
insertar comandos de secuencias de comandos en las páginas HTML.

Puede incluir procedimientos escritos en su lenguaje predeterminado de secuencias de comandos


dentro de delimitadores ASP. Para obtener más información, consulte Trabajar con lenguajes de
secuencias de comandos.

Si va a trabajar con comandos JScript, puede insertar las llaves que indican un bloque de
instrucciones directamente en sus comandos ASP, incluso aunque estén entremezclados con
etiquetas y texto HTML. Por ejemplo:

<%

if (screenresolution == "low")

%>

Ésta es la versión de texto de la página.

<%

else

%>

Ésta es la versión multimedia de la página.

<%

119
}

%>

-O bien-

<%

if (screenresolution == "low")

Response.Write("Ésta es la versión de texto de la página.")

else

Response.Write("Ésta es la versión multimedia de la página.")

%>

Utilizar directivas ASP

ASP proporciona directivas que no forman parte de los lenguajes de secuencias de comandos:
Dichas directivas son la directiva de resultado y la directiva de proceso.

La directiva de resultado de ASP <%= expresión %> presenta el valor de una expresión. Dicha
directiva es equivalente al uso de Response.Write para presentar información. Por ejemplo, la
expresión <%= ciudad %> envía al explorador la palabra Barcelona (el valor actual de la variable).

La directiva de proceso de ASP <%@ palabra clave %> ofrece a ASP la información que necesita
para procesar un archivo .asp. Por ejemplo, la siguiente directiva establece VBScript como
lenguaje principal de secuencia de comandos de la página:

<%@ LANGUAGE=VBScript %>

Las directivas de proceso deben estar en la primera línea de los archivos .asp. Para agregar más
de una directiva a una página, deben incluirse en el mismo delimitador. No ponga las directivas de
proceso en los archivos incluidos con la instrucción #include. Debe incluir un espacio en blanco
entre el signo @ y la palabra clave. La directiva de proceso tiene las siguientes palabras clave:

• La palabra clave LANGUAGE establece el lenguaje principal de secuencia de comandos


de la página.
• La palabra clave ENABLESESSIONSTATE especifica si un archivo ASP utiliza el estado
de la sesión. Consulte Administrar sesiones.
• La palabra clave CODEPAGE establece la página de códigos (la codificación de
caracteres) del archivo .asp.

120
• La palabra clave LCID establece el identificador de configuración regional del archivo.
• La palabra clave TRANSACTION especifica que el archivo .asp se ejecutará dentro del
contexto de una transacción. Consulte Descripción de las transacciones

Importante Puede incluir más de una palabra clave en una única directiva. Los pares de palabra
clave y valor deben estar separados por un espacio. No ponga espacios ni antes ni después del
signo igual (=).

El ejemplo siguiente establece el lenguaje de secuencia de comandos y la página de códigos:

<%@ LANGUAGE="Jscript" CODEPAGE="932" %>

Espacio en blanco en las secuencias de comandos

Si su lenguaje principal de secuencias de comandos es VBScript o JScript, ASP quita el espacio en


blanco de los comandos. En otros lenguajes, ASP conserva el espacio en blanco para que los
lenguajes que interpreten la posición o la sangría puedan interpretarlo correctamente. El espacio
en blanco incluye espacios, tabuladores, retornos y saltos de línea.

En VBScript y JScript puede utilizar el espacio en blanco que sigue al delimitador de apertura y que
precede al de cierre para facilitar la lectura de los comandos. Todas las instrucciones siguientes
son válidas:

<% Color = "Green" %>

<%Color="Green"%>

<%

Color = "Green"

%>

ASP quita el espacio en blanco que se encuentre entre los delimitadores de cierre de las
instrucciones y los delimitadores de apertura de las instrucciones siguientes. Sin embargo, se
recomienda utilizar espacios para mejorar la legibilidad. Si tiene que conservar el espacio en
blanco entre dos instrucciones, como cuando vaya a presentar los valores de las variables en una
frase, utilice el carácter de espacio de no separación de HTML (&nbsp;). Por ejemplo:

<%

'Define dos variables con valores de cadena.

strFirstName = "Juan"

strLastName = "García"

%>

<P>Esta página Web está personalizada para "<%= strFirstName %>&nbsp;<%=


strLastName %>." </P>

121
Utilizar variables y constantes

Una variable es una ubicación de almacenamiento con nombre dentro de la memoria del equipo
que contiene datos, como un número o una cadena de texto. A los datos contenidos en una
variable se les llama valor de la variable. Las variables ofrecen una manera de almacenar,
recuperar y manipular valores mediante nombres que ayuden a entender lo que hace la secuencia
de comandos.

Declarar y asignar nombre a variables

Siga las reglas y recomendaciones de su lenguaje de secuencias de comandos a la hora de


declarar variables y asignarles nombres. Incluso aunque no necesita declarar una variable para
poder utilizarla, es conveniente hacerlo porque ayuda a prevenir errores. Declarar una variable
significa indicar al motor de secuencias de comandos que existe una variable con un nombre
concreto, de forma que pueda hacer referencia a la variable a lo largo de una secuencia de
comandos.

VBScript

VBScript no necesita declaraciones de variables, pero es conveniente declarar todas las variables
antes de utilizarlas. Para declarar una variable en VBScript, utilice la instrucción Dim, Public o
Private. Por ejemplo:

<% Dim NombreUsuario %>

Puede utilizar la instrucción Option Explicit de VBScript en los archivos .asp para hacer obligatoria
la declaración de variables con las instrucciones Dim, Private, Public y ReDim. La instrucción
Option Explicit debe aparecer después de las directivas ASP y antes del texto HTML o de los
comandos de la secuencia de comandos. Esta instrucción sólo afecta a los comandos ASP escritos
en VBScript; no afecta a los comandos escritos en JScript.

<% Option Explicit %>

<HTML>

<%

Dim strNombreUsuario

Public lngNumeroCuenta

%>

Alcance de las variables

El alcance, o vida, de una variable determina qué comandos de secuencia de comandos pueden
tener acceso a dicha variable. Una variable declarada dentro de un procedimiento tiene alcance
local; la variable se crea y se destruye cada vez que se ejecuta el procedimiento. No se puede
tener acceso a ella desde fuera del procedimiento. Una variable declarada fuera de un
procedimiento tiene alcance global; su valor es accesible y modificable desde cualquier comando
de secuencia de comandos de una página ASP.

122
Nota Al limitar el alcance de la variable a un procedimiento mejorará el rendimiento.

Si declara variables, una variable local y una variable global pueden tener el mismo nombre. La
modificación del valor de una de ellas no afecta al valor de la otra. Sin embargo, si no declara las
variables, podría modificar inadvertidamente el valor de una variable global. Por ejemplo, los
siguientes comandos de secuencia de comandos devuelven el valor 1 incluso aunque haya dos
variables llamadas Y:

<%

Option Explicit

Dim Y

Y = 1

SetLocalVariable

Response.Write Y

Sub SetLocalVariable

Dim Y

Y = 2

End Sub

%>

Por el contrario, los comandos siguientes devuelven el valor 2 porque las variables no se han
declarado de forma explícita. Cuando la llamada al procedimiento asigna a Y el valor 2, el motor de
secuencias de comandos da por supuesto que el procedimiento pretende modificar la variable
global:

<%

Option Explicit

Dim Y = 1

SetLocalVariable

Response.Write Y

Sub SetLocalVariable

Y = 2

End Sub

%>

123
Para evitar problemas, adquiera el hábito de declarar explícitamente todas las variables. Lo cual es
especialmente importante si utiliza la instrucción #include para incluir archivos en su archivo ASP.
La secuencia de comandos incluida está contenida en un archivo aparte, pero se trata como si
formara parte del archivo contenedor. Es muy fácil olvidarse de que hay que utilizar nombres de
variables diferentes en la secuencia de comandos principal y en la secuencia de comandos
incluida, a menos que declare las variables.

Asignar a las variables alcance de sesión o de aplicación

Las variables globales sólo son accesibles en un mismo archivo ASP. Para hacer que una variable
sea accesible en varias páginas, asigne a la variable alcance de sesión o de aplicación. Las
variables con alcance de sesión están disponibles en todas las páginas de una aplicación ASP que
pida un mismo usuario. Las variables con alcance de aplicación están disponibles en todas las
páginas de una aplicación ASP que pida cualquier usuario. Las variables de sesión son una buena
manera de almacenar información para un único usuario, como sus preferencias o el nombre o la
identificación del usuario. Las variables de aplicación son una buena manera de almacenar
información para todos los usuarios de una determinada aplicación, como los saludos específicos o
los valores generales necesarios en la aplicación.

ASP proporciona dos objetos integrados en los que puede almacenar variables: el objeto Session y
el objeto Application.

También puede crear instancias de objetos con alcance de sesión o de aplicación. Para obtener
más información, consulte Establecer el alcance de los objetos.

Alcance de sesión

Para asignar alcance de sesión a una variable, almacénela en el objeto Session asignando un valor
a una entrada con nombre del objeto. Por ejemplo, los siguientes comandos almacenan dos
nuevas variables en el objeto Session:

<%

Session("Nombre") = "Juan"

Session("Apellido") = "Soto"

%>

Para recuperar la información del objeto Session, tenga acceso a la entrada con nombre mediante
la directiva de resultado (<%=) o Response.Write. En el ejemplo siguiente se utiliza la directiva de
resultado para presentar el valor actual de Session("Nombre"):

Reciba nuestra bienvenida,<%= Session("Nombre") %>

Puede almacenar las preferencias del usuario en el objeto Session y después tener acceso a
dichas preferencias para determinar qué página hay que devolver al usuario. Por ejemplo, puede
permitir que los usuarios especifiquen la versión en texto del contenido de la primera página de la
aplicación y aplicar esta opción a las siguientes páginas de la aplicación que el usuario visite.

<%

strScreenResolution = Session("ScreenResolution")

124
If strScreenResolution = "Low" Then

%>

Ésta es la versión de texto de la página.

<% Else %>

Ésta es la versión multimedia de la página.

<%End If %>

Nota Si hace referencia a una variable con alcance de sesión más de una vez en una secuencia
de comandos, piense en asignarle una variable local, como en el ejemplo anterior, para mejorar el
rendimiento.

Alcance de aplicación

Para asignar alcance de aplicación a una variable, almacénela en el objeto Application asignando
un valor a una entrada con nombre del objeto. Por ejemplo, el comando siguiente almacena en el
objeto Application un saludo específico de una aplicación:

<% Application("Saludo") = "¡Reciba nuestra bienvenida al Departamento de


ventas!" %>

Para recuperar la información del objeto Application, utilice la directiva de resultado de ASP (<%=)
o Response.Write para tener acceso a la entrada con nombre desde cualquier página posterior de
la aplicación. En el ejemplo siguiente se utiliza la directiva de resultado para presentar el valor de
Application("Saludo"):

<%= Application("Saludo") %>

De nuevo, si hace referencia a una variable con alcance de aplicación en su secuencia de


comandos repetidamente, debe de asignarle una variable local para mejorar el rendimiento.

Utilizar constantes

Una constante es un nombre que representa un número o una cadena. Algunos de los
componentes de base que se proporcionan con ASP, como ActiveX Data Objects (ADO), definen
constantes que se pueden utilizar en las secuencias de comandos. Un componente puede declarar
constantes en la biblioteca de tipos del componente, un archivo que contiene información acerca
de los objetos y los tipos aceptados por un componente COM. Después de haber declarado una
biblioteca de tipos en su archivo .asp puede usar las constantes definidas en cualquier secuencia
de comandos en el mismo archivo .asp. Igualmente, puede declarar una biblioteca de tipos en el
archivo Global.asa para usar las constantes definidas en cualquier archivo .asp de la aplicación.

Para declarar una biblioteca de tipos, utilice la etiqueta <METADATA> en su archivo .asp o
Global.asa. Por ejemplo, para declarar la biblioteca de tipos de ADO, utilice las siguientes
instrucciones:

<!--METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library"


TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}"-->

125
O bien, en lugar de hacer referencia al identificador único universal (UUID) de la biblioteca de tipos,
puede hacer referencia a la biblioteca de tipos mediante la ruta del archivo:

<!-- METADATA TYPE="typelib" FILE="c:\program files\common


files\system\ado\msado15.dll"-->

Entonces puede usar las constantes ADO en el archivo .asp donde declaró la biblioteca de tipos o
en un archivo que reside en una aplicación que contiene un archivo Global.asa con la declaración
de biblioteca de tipos ADO. En el ejemplo siguiente, adOpenKeyset y adLockOptimistic son
constantes ADO:

<%

'Crea y abre el objeto Recordset.

Set rsCustomersList = Server.CreateObject("ADODB.Recordset")

rstCustomerList.ActiveConnection = cnnPubs

rstCustomerList.CursorType = adOpenKeyset

rstCustomerList.LockType = adLockOptimistic

%>

En la siguiente tabla se enumeran las bibliotecas de tipos y los identificadores UUID que se utilizan
con más frecuencia:

Biblioteca de tipos UUID


Biblioteca de Microsoft ActiveX Data {00000205-0000-0010-8000-00AA006D2EA4}
Objects 2.5
Biblioteca de Microsoft CDO 1.2 para {0E064ADD-9D99-11D0-ABE5-00AA0064D470}
Windows 2000 Server
Biblioteca MSWC de objetos {090ACFA1-1580-11D1-8AC0-00C0F00910F9}
Advertisement Rotator
Biblioteca MSWC de objetos de registro {B758F2F9-A3D6-11D1-8B9C-080009DCC2FA}
de IIS

Interactuar con secuencias de comandos del cliente

Es posible aumentar la eficacia de ASP si se utiliza para generar o manipular secuencias de


comandos del cliente. Por ejemplo, puede escribir secuencias de comandos del servidor que
construyan secuencias de comandos del cliente basadas en variables específicas del servidor, el
tipo del explorador o los parámetros de la petición HTTP.

Si intercala instrucciones de secuencias de comandos del servidor en las secuencias de comandos


del cliente (delimitadas mediante etiquetas HTML <SCRIPT>), como se muestra en la plantilla del
ejemplo siguiente, puede inicializar de forma dinámica y alterar las secuencias de comandos del
cliente en el momento de realizar la petición:

<SCRIPT LANGUAGE="VBScript">

126
<!--

variable = <%=valor definido por el servidor %>

secuencia de comandos del cliente

<% secuencia de comandos del servidor que se utiliza para generar una
instrucción del cliente %>

secuencia de comandos del cliente

-->

</SCRIPT>

Al incorporar estas funciones es posible crear algunas aplicaciones útiles e interesantes. Por
ejemplo, ésta es una sencilla secuencia de comandos del servidor (escrita en VBScript) que
manipula una secuencia de comandos del cliente (escrita en JScript):

<%

Dim dtmTime, strServerName, strServerSoftware, intGreeting

dtmTime = Time()

strServerName = Request.ServerVariables("SERVER_NAME")

strServerSoftware = Request.ServerVariables("SERVER_SOFTWARE")

'Genera un número aleatorio.

Randomize

GreetCondition = int(rnd * 3)

%>

<SCRIPT LANGUAGE="JScript">

127
<!--

//Llama a la función para mostrar el saludo

showIntroMsg()

function showIntroMsg()

switch(<%= intGreeting %>)

case 0:

msg = "Este es el servidor Web <%= strServerName%> con <%=


strServerSoftware %>."

break

case 1:

msg = "Reciba nuestra bienvenida al servidor Web <%= strServerName%>. La


hora local es <%= dtmTime %>."

break

case 2:

msg = "Este servidor utiliza <%= strServerSoftware %>."

break

document.write(msg)

-->

</SCRIPT>

Escribir procedimientos

Un procedimiento es un grupo de comandos de secuencia de comandos que realizan una tarea


específica y puede devolver un valor. Puede definir sus propios procedimientos e invocarlos
repetidamente desde sus secuencias de comandos.

128
Puede poner las definiciones de los procedimientos en el mismo archivo .asp que llama a los
procedimientos o bien puede poner los procedimientos utilizados con más frecuencia en un archivo
.asp compartido y utilizar la directiva #include para incluirlo en otros archivos .asp que llamen a los
procedimientos. Como alternativa, puede encapsular dicha funcionalidad en un componente COM.

Definir procedimientos

Las definiciones de los procedimientos pueden encontrarse dentro de etiquetas <SCRIPT> y


</SCRIPT> y deben seguir las reglas del lenguaje de secuencias de comandos. Utilice el elemento
<SCRIPT> para los procedimientos escritos en lenguajes distintos del lenguaje principal para
secuencias de comandos. Sin embargo, utilice los delimitadores de las secuencias de comandos (<
% y %>) en los procedimientos escritos en el lenguaje principal de secuencias de comandos.

Cuando utilice la etiqueta HTML <SCRIPT>, debe emplear dos atributos para asegurar el proceso
de la secuencia de comandos por parte del servidor. La sintaxis de la etiqueta <SCRIPT> es la
siguiente:

<SCRIPT LANGUAGE=JScript RUNAT=SERVER>

definición del procedimiento

</SCRIPT>

El atributo RUNAT=SERVER indica al servidor Web que procese la secuencia de comandos en el


servidor. Si no establece este atributo, la secuencia de comandos la procesará el explorador del
cliente. El atributo LANGUAGE determina el lenguaje de secuencia de comandos utilizado en este
bloque. Puede especificar cualquier lenguaje para el que haya instalado un motor de secuencias de
comandos en el servidor. Para especificar VBScript, use el valor VBScript. Para especificar JScript,
use el valor JScript. Si no asigna el atributo LANGUAGE, el bloque de la secuencia de comandos
se interpretará en el lenguaje principal de secuencia de comandos.

Los comandos del bloque de la secuencia de comandos deben componer uno o varios
procedimientos completos en el lenguaje de secuencia de comandos elegido. Por ejemplo, los
comandos siguientes definen el procedimiento JScript MiFuncion.

<HTML>

<SCRIPT LANGUAGE=JScript RUNAT=SERVER >

function MiFuncion()

Response.Write("Llamó a MiFuncion().")

</SCRIPT>

Importante No incluya en las etiquetas <SCRIPT> del servidor comandos de secuencias de


comandos que no formen parte de procedimientos completos. Los comandos que no formen parte
de un procedimiento pueden provocar resultados impredecibles puesto que deben ejecutarse en un

129
orden determinado. Además, no puede utilizar la directiva de resultado de ASP <%=%> dentro de
los procedimientos. En su lugar, utilice Response.Write para enviar contenido al explorador.

Llamar a procedimientos

Para llamar a procedimientos, incluya el nombre de los procedimientos en un comando. Si va a


llamar a procedimientos JScript desde VBScript, debe utilizar paréntesis después del nombre del
procedimiento; si el procedimiento no tiene argumentos, utilice paréntesis vacíos. Si va a llamar a
procedimientos VBScript o JScript desde JScript, utilice siempre paréntesis después del nombre
del procedimiento.

En VBScript también puede utilizar la palabra clave Call para llamar a un procedimiento. Sin
embargo, si el procedimiento al que llama requiere argumentos, la lista de argumentos debe
aparecer entre paréntesis. Si omite la palabra clave Call, también debe omitir los paréntesis en los
que se incluye la lista de argumentos. Si utiliza la sintaxis Call para llamar a una función integrada
o definida por el usuario, se descartará el valor devuelto por la función.

El ejemplo siguiente ilustra la creación y la llamada a procedimientos en dos lenguajes para


secuencias de comandos diferentes (VBScript y JScript).

<%@ LANGUAGE=VBScript %>

<HTML>

<BODY>

<% Echo %>

<BR>

<% printDate() %>

</BODY>

</HTML>

<%

Sub Echo

Response.Write "<TABLE>" & _

"Response.Write "<TR><TH>Nombre</TH><TH>Valor</TH></TR>"

Set objQueryString = Request.QueryString

For Each strSelection In objQueryString

Response.Write "<TR><TD>" & p & "</TD><TD>" & _

FormValues(strSelection) & "</TD></TR>"

130
Next

Response.Write "</TABLE>"

End Sub

%>

<SCRIPT LANGUAGE=JScript RUNAT=SERVER>

function PrintDate()

var x

x = new Date()

Response.Write(x.toString())

</SCRIPT>

Las llamadas de VBScript a las funciones JScript no distinguen entre mayúsculas y minúsculas.

Pasar matrices a procedimientos

Para pasar una matriz entera a un procedimiento en VBScript, utilice el nombre de la matriz
seguido de paréntesis vacíos; en JScript, utilice corchetes vacíos.

Procesar los datos proporcionados por el usuario

Mediante el objeto Request de ASP puede crear sencillas y eficaces secuencias de comandos para
recopilar y procesar datos obtenidos de formularios HTML. En este tema no sólo aprenderá a crear
secuencias de comandos básicas para procesar formularios, sino que también conocerá técnicas
útiles para validar los datos de los formularios, tanto en su servidor Web como en el explorador de
Web del usuario.

Acerca de los formularios HTML

Los formularios HTML, el método más común para recopilar información desde el Web, consiste en
un conjunto de etiquetas HTML especiales que presentan elementos de interfaz de usuario en una
página Web. Los cuadros de texto, los botones y las casillas de verificación son ejemplos de
elementos que permiten que los usuarios intercalen con una página Web y envíen información a un
servidor Web.

Por ejemplo, las siguientes etiquetas HTML generan un formulario en el que un usuario puede
escribir su nombre, apellido y edad, e incluye un botón para enviar la información a un servidor
Web. El formulario también contiene una etiqueta de entrada oculta (no presentada por el
explorador Web) que puede utilizar para pasar información adicional al servidor Web.

131
<FORM METHOD="Post" ACTION="Profile.asp">

<INPUT TYPE="text" NAME="Nombre">

<INPUT TYPE="text" NAME="Apellido">

<INPUT TYPE="text" NAME="Edad">

<INPUT TYPE="Hidden" NAME="EstadoUsuario" VALUE="Nuevo">

<INPUT TYPE="Submit" VALUE="Entrar">

</FORM>

Presentar con detalle el conjunto completo de etiquetas HTML para formularios se sale del ámbito
de este tema, sin embargo, hay numerosas fuentes de información que puede utilizar para
aprender a crear y utilizar formularios HTML. Por ejemplo, puede utilizar la posibilidad que ofrece
su explorador para ver el código fuente con el fin de examinar cómo se crean los formularios HTML
en otros sitios Web. También puede visitar el sitio Web de MSDN de Microsoft en la dirección
http://msdn.microsoft.com/ para conocer las técnicas más recientes para utilizar los formularios
HTML con otras tecnologías de Internet.

Procesar datos de formularios con ASP

Después de crear el formulario HTML tendrá que procesar los datos proporcionados por el usuario,
lo que implica enviar la información a un archivo .asp para que la analice y manipule. De nuevo,
examine el código HTML del ejemplo anterior. Observe que el atributo ACTION de la etiqueta
<FORM> hace referencia a un archivo llamado Profile.asp. Cuando el usuario envía información
HMTL, el explorador utiliza el método POST para enviarla a un archivo .asp del servidor, en este
caso Profile.asp. Este archivo .asp puede contener archivos de comandos que procesen la
información e interactúen con otras secuencias de comandos, componentes COM o recursos,
como una base de datos.

Existen tres formas básicas de recopilar información de un formulario HTML mediante ASP:

• Un archivo .htm estático puede contener un formulario que envíe sus valores a un
archivo .asp.
• Un archivo .asp puede crear un formulario que envíe información a otro archivo .asp.
• Un archivo .asp puede crear un formulario que se envíe información a sí mismo; es decir,
al archivo .asp que contiene el formulario.

Los dos primeros métodos funcionan igual que los formularios que interactúan con otros programas
de servidor Web, con la única diferencia de que con ASP se simplifica mucho la tarea de recuperar
y procesar la información. El tercer método es especialmente útil y se muestra en la sección Validar
los datos de los formularios.

Obtener datos de los formularios

El objeto Request de ASP proporciona dos colecciones que facilitan la tarea de recuperar
información de los formularios enviados con las peticiones URL.

La colección QueryString

132
La colección QueryString recupera los valores del formulario pasados al servidor Web como texto a
continuación del signo de interrogación de la dirección URL de la petición. Los valores del
formulario se pueden anexar a la dirección URL de la petición mediante el método GET de HTTP o,
manualmente, si se agregan los valores del formulario a la dirección URL.

Si el ejemplo del formulario anterior utilizara el método GET (METHOD = "GET") y el usuario
escribiera Juan, Soto y 30, se enviaría la siguiente petición URL al servidor:

http://Workshop1/Painting/Profile.asp?
Nombre=Juan&Apellido=Soto&Edad=30&EstadoUsuario=Nuevo

El archivo Profile.asp podría contener la siguiente secuencia de comandos para procesar


formularios:

Hola, <%= Request.QueryString("nombre") %> <%=


Request.QueryString("apellido") %>.

Tiene <%= Request.QueryString("edad") %> años.

<%

If Request.QueryString("EstadoUsuario") = "Nuevo" Then

Response.Write"Ésta es su primera visita a este sitio Web"

End if

%>

En este caso, el servidor Web devolvería el texto siguiente al explorador Web del usuario:

Hola Juan Soto. Tiene 30 años. Ésta es su primera visita a este sitio Web

La colección QueryString también tiene un parámetro opcional que puede utilizar para tener acceso
a uno de los múltiples valores que se encuentran en el cuerpo de la petición URL (con el método
GET). También puede utilizar la propiedad Count para contar el número de veces que aparece un
determinado tipo de valor.

Por ejemplo, un formulario que contenga un cuadro de lista con varios elementos puede generar la
siguiente petición:

http://OrganicFoods/list.asp?Comida=Manzanas&Comida=Aceitunas&Comida=Pan

Podría utilizar el siguiente comando para contar los diferentes valores:

Request.QueryString("Comida").Count

Para presentar los tipos de valores, Lista.asp podría contener la


secuencia de comandos siguiente:

<%

133
lngTotal = Request.QueryString("Comida").Count

For i = 1 To lngTotal

Response.Write Request.QueryString("Comida")(i) & "<BR>"

Next

%>

La secuencia de comandos anterior mostraría:

Manzanas

Aceitunas

Pan

También puede mostrar la lista completa de valores como una cadena delimitada por comas, del
modo siguiente:

<% Response.Write Request.QueryString("Item") %>

Aparecería la cadena siguiente:

Manzanas, Aceitunas, Pan

Colección Form

Cuando utiliza el método GET de HTTP para pasar a un servidor Web valores de un formulario
grande y complejo, corre el riesgo de perder información. Algunos servidores Web tienden a
restringir el tamaño de la cadena de petición de URL, por lo que los valores de los formularios
grandes pasados con el método GET podrían quedar truncados. Si necesita enviar una gran
cantidad de información desde un formulario a un servidor Web, debe utilizar el método POST de
HTTP. El método POST, que envía los datos de los formularios en el cuerpo de la petición HTTP,
puede enviar un número casi ilimitado de caracteres a un servidor. Puede utilizar la colección Form
del objeto Request de ASP para recuperar los valores enviados mediante el método POST.

La colección Form almacena valores de manera similar a la colección QueryString. Por ejemplo, si
un usuario completa un formulario escribiendo una larga lista de nombres, se podrían leer los
nombres con la secuencia de comandos siguiente:

<%

lngTotal = Request.Form("Comida").Count

For i = 1 To lngTotal

Response.Write Request.Form("Comida")(i) & "<BR>"

Next

134
%>

Validar los datos de los formularios

Un formulario Web bien diseñado suele incluir una secuencia de comandos del cliente que valida
los datos proporcionados por el usuario antes de enviar la información al servidor. Las secuencias
de comandos de validación pueden comprobar si el usuario escribió un número válido o si un
cuadro de texto está en blanco. Imagine que su sitio Web incluye un formulario que permite
calcular la tasa de retorno de una inversión. Probablemente querrá comprobar si un usuario
realmente escribió texto o números en los campos apropiados del formulario, antes de enviar al
servidor información que podría no ser válida.

En general, lo mejor es realizar en el cliente tantas comprobaciones como sea posible. Además, de
poder preguntar antes al usuario por los errores, la validación en el cliente mejora el tiempo de
respuesta, reduce la carga del servidor y libera ancho de banda para otras aplicaciones.

La siguiente secuencia de comandos del cliente valida los datos escritos por el usuario (en este
caso, la secuencia de comandos determina si el número de cuenta que escribió el usuario es
realmente un número) antes de enviarlos al servidor:

<SCRIPT LANGUAGE="JScript">

function ComprobarNumero()

if (isNumeric(document.UserForm.AcctNo.value))

return true

else

alert("Escriba un número de cuenta válido.")

return false

//Función para determinar si el valor del formulario es un número.

//Nota: El método isNaN JScript es un método más elegante para determinar


si

//un valor no es un número. Sin embargo, algunos exploradores no admiten


este método.

function isNumeric(str)

135
{

for (var i=0; i < str.length; i++)

var ch = str.substring(i, i+1)

if( ch < "0" || ch>"9" || str.length == null)

return false

return true

</SCRIPT>

<FORM METHOD="Get" ACTION="balance.asp" NAME="FormularioUsuario"


ONSUBMIT="return CheckNumber()">

<INPUT TYPE="Text" NAME="NumCuen">

<INPUT TYPE="Submit" VALUE="Enviar">

</FORM>

Sin embargo, si la validación de un formulario requiere el acceso a una base de datos debe
considerar la utilización de la validación del formulario en el servidor. Una forma muy útil de realizar
la validación en el servidor es crear formularios que se envíen la información a sí mismos. Es decir,
el archivo .asp contiene en realidad el formulario HTML que recibe los datos del usuario.
(Recuerde, puede utilizar ASP para interactuar con secuencias de comandos del cliente y código
HTML. Para obtener más información, consulte Interactuar con secuencias de comandos del
cliente.) Los datos escritos vuelven al mismo archivo, que se encarga de validar la información y
avisa al usuario si éstos no son correctos.

Mediante este método se pueden mejorar las características de uso y la respuesta de los
formularios basados en Web. Por ejemplo, si se incluye información del error junto al campo del
formulario en el que se escribió la información incorrecta, será más fácil para el usuario descubrir el
origen del error. (Normalmente, los formularios basados en Web reenvían las peticiones a una
página Web independiente que contiene información del error. Los usuarios que no comprendan
esta información podrían sentirse frustrados.)

Por ejemplo, la secuencia de comandos siguiente determina si un usuario escribió un número de


cuenta válido, para lo que se envía la información a sí misma (Verify.asp) y llama a una función
definida por el usuario que realiza una consulta a una base de datos:

136
<%

strAcct = Request.Form("Cuenta")

If Not AccountValid(strAcct) Then

ErrMsg = "<FONT COLOR=Red>El número de cuenta que ha escrito no es


válido.</FONT>"

Else

Procesa los datos del usuario

Server.Transfer("Complete.asp")

End If

Function AccountValid(strAcct)

Aquí se incluirá una secuencia de comandos o una llamada a un método de


un componente de conexión con una base de datos.

End Function

%>

<FORM METHOD="Post" ACTION="Verify.asp">

Número de cuenta: <INPUT TYPE="Text" NAME="Cuenta"> <%= ErrMsg %> <BR>

<INPUT TYPE="Submit">

</FORM>

En este ejemplo, la secuencia de comandos se encuentra en un archivo llamado Verify.asp, el


mismo archivo que contiene el formulario HTML y, para enviarse la información a sí mismo,
especifica Verify.asp en el atributo ACTION.

Importante Si utiliza JScript para la validación en el servidor, asegúrese de colocar un par de


paréntesis vacíos detrás del elemento de la colección Request (QueryString o Form) al asignar la
colección a una variable local. Sin el paréntesis la colección devolverá un objeto en lugar de una
cadena. La secuencia de comandos siguiente muestra el método correcto para asignar variables
con JScript:

<%

137
var Nombre = Request.Form("Nombre")();

var Contraseña = Request.Form("Contraseña")();

if(Nombre > "")

if(Nombre == Contraseña)

Response.Write("El nombre y la contraseña son iguales".)

else

Response.Write("El nombre y la contraseña son diferentes".);

%>

VBScript presenta el mismo comportamiento si la colección contiene varios valores separados por
comas o con los que se pueda crear un índice. Esto significa que tanto para VBScript como para
JScript, además de colocar un par de paréntesis detrás del elemento de la colección Request,
necesitará especificar el índice del valor deseado. Por ejemplo, la siguiente línea en JScript
devuelve sólo el primero de los varios valores de un elemento de un formulario:

var Nombre = Request.Form("Nombre")(1);

Acceso al origen de datos

ActiveX Data Objects (ADO) es una tecnología ampliable y de fácil uso para agregar a sus páginas
Web acceso a bases de datos. Puede utilizar ADO para escribir secuencias de comandos
compactas y escalables que le permitan conectarse a orígenes de datos compatibles con OLE DB,
como bases de datos, hojas de cálculo, archivos de datos secuenciales o directorios de correo
electrónico. OLE DB es una interfaz de programación de nivel de sistema que proporciona un
conjunto estándar de interfaces COM para que permitan exponer las funciones del sistema de
administración de bases de datos. Con el modelo de objetos ADO es fácil tener acceso a estas
interfaces (mediante lenguajes de secuencias de comandos, como VBScript o JScript) para
agregar funciones de bases de datos a las aplicaciones Web. Además, también puede utilizar ADO
para tener acceso a bases de datos compatibles con la Conectividad abierta de bases de datos
(ODBC, Open Database Connectivity).

Si no tiene mucha experiencia en conectividad con bases de datos, encontrará que la sintaxis de
ADO es sencilla y fácil de utilizar. Si es un programador experimentado, agradecerá el acceso
escalable de alto rendimiento que proporciona ADO para una gran variedad de orígenes de datos.

Crear una cadena de conexión

El primer paso en la creación de una aplicación de datos en Web consiste en proporcionar un


método para que ADO encuentre e identifique el origen de datos. Para ello se utiliza una cadena de
conexión, una serie de argumentos separados mediante un punto y coma que definen parámetros
como el proveedor del origen de datos y la ubicación del mismo. ADO utiliza la cadena de conexión
para identificar el proveedor OLE DB y para dirigir al proveedor al origen de datos. El proveedor es

138
un componente que representa el origen de datos y que expone la información en la aplicación en
forma de conjuntos de filas.

En la tabla siguiente se enumeran las cadenas de conexión de OLE DB para varios orígenes de
datos habituales:

Origen de datos Cadena de conexión OLE DB


Microsoft(r) Access Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ruta física de acceso
al archivo .mdb
Microsoft SQL Server Provider=SQLOLEDB.1;Data Source=ruta de acceso a la base de
datos del servidor
Oracle Provider=MSDAORA.1;Data Source=ruta de acceso a la base de
datos del servidor
Microsoft Indexing Service Provider=MSIDXS.1;Data Source=ruta de acceso al archivo

Para proporcionar compatibilidad con versiones anteriores, el proveedor OLE DB para ODBC
admite la sintaxis de las cadenas de conexión ODBC. En la tabla siguiente se enumeran las
cadenas de conexión ODBC que se utilizan habitualmente:

Controlador del origen de Cadena de conexión ODBC


datos
Microsoft Access Driver={Microsoft Access Driver (*.mdb)};DBQ=ruta física de acceso al
archivo .mdb
SQL Server DRIVER={SQL Server};SERVER=ruta de acceso al servidor
Oracle DRIVER={Microsoft ODBC for Oracle};SERVER=ruta de acceso al
servidor
Microsoft Excel Driver={Microsoft Excel Driver (*.xls)};DBQ=ruta física de acceso al
archivo .xls; DriverID=278
Microsoft Excel 97 Driver={Microsoft Excel Driver (*.xls)};DBQ=ruta física de acceso al
archivo .xls;DriverID=790
Paradox Driver={Microsoft Paradox Driver (*.db)};DBQ=ruta física de acceso al
archivo .db;DriverID=26
Texto Driver={Microsoft Text Driver (*.txt;*.csv)};DefaultDir=ruta física de
acceso al archivo .txt
Microsoft Visual FoxPro(r) Driver={Microsoft Visual FoxPro
(con un contenedor de bases Driver};SourceType=DBC;SourceDb=ruta física de acceso al
de datos) archivo .dbc
Microsoft Visual FoxPro (sin Driver={Microsoft Visual FoxPro
un contenedor de bases de Driver};SourceType=DBF;SourceDb=ruta física de acceso al archivo
datos) .dbf

Conectarse al origen de datos

ADO proporciona el objeto Connection para establecer y administrar las conexiones entre las
aplicaciones y los orígenes de datos compatibles con OLE DB o las bases de datos compatibles
con ODBC. El objeto Connection incorpora propiedades y métodos que se pueden utilizar para
abrir y cerrar conexiones con bases de datos, y para enviar consultas de actualización de la
información.

139
Para establecer una conexión con una base de datos, cree primero una instancia del objeto
Connection. Por ejemplo, la secuencia de comandos siguiente crea una instancia del objeto
Connection y procede a abrir una conexión:

<%

'Crea un objeto Connection.

Set cn = Server.CreateObject("ADODB.Connection")

'Abre una conexión mediante la cadena de conexión OLE DB.

cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\DatosMercado\VentasPrevistas.mdb"

%>

La cadena de conexión no contiene espacios en blanco ni antes ni después del signo igual (=).

En este caso, el método Open del objeto Connection se refiere a la cadena de conexión.

Ejecutar consultas SQL con el objeto Connection

Con el método Execute del objeto Connection puede emitir comandos al origen de datos, como
consultas de SQL (Lenguaje de consulta estructurado). (SQL, lenguaje estándar para comunicarse
con bases de datos, define comandos para recuperar y actualizar información.) El método Execute
acepta parámetros que especifiquen el comando (o la consulta), el número de registros de datos a
los que afecta y el tipo de comando que se utiliza.

La siguiente secuencia de comandos utiliza el método Execute para enviar una consulta con un
comando INSERT de SQL, que inserta datos en una tabla concreta de la base de datos. En este
caso, el bloque de la secuencia de comandos inserta el nombre José Lugo en una tabla de la base
de datos llamada Customers.

<%

'Define la cadena de conexión OLE DB.

strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\Datos\Empleados.mdb"

'Crea la instancia del objeto Connection y abre una conexión con la base
de datos.

Set cn = Server.CreateObject("ADODB.Connection")

cnn.Open strConnectionString

'Define la instrucción SELECT de SQL.

strSQL = "INSERT INTO Customers (FirstName, LastName) VALUES


('José','Lugo')"

140
'Utiliza el método Execute para enviar una consulta SQL a la base de
datos.

cnn.Execute strSQL,,adCmdText + adExecuteNoRecords

%>

Observe que se especifican dos parámetros en la instrucción que se utiliza para ejecutar la
consulta: adCmdText y adExecuteNoRecords. El parámetro opcional adCmdText especifica el tipo
de comando e indica que el proveedor debe evaluar la instrucción de consulta (en este caso, una
consulta SQL) como una definición textual de un comando. El parámetro adExecuteNoRecords
indica a ADO que no debe crear un conjunto de registros de datos si no se devuelven resultados a
la aplicación. Este parámetro sólo funciona con los tipos de comandos definidos como texto, como
las consultas SQL, o con procedimientos almacenados de bases de datos. Aunque los parámetros
adCmdText y adExecuteNoRecords son opcionales, debe especificarlos al utilizar el método
Execute para mejorar así el rendimiento de la aplicación de datos.

Importante Los parámetros ADO, como adCmdText, deben estar definidos para poder utilizarlos
en una secuencia de comandos. Un método cómodo para definir los parámetros consiste en utilizar
una biblioteca de tipos de componentes, que es un archivo que contiene definiciones para todos los
parámetros ADO. Para implementar una biblioteca de tipos de componentes debe declararla antes.
Agregue la etiqueta siguiente <METADATA> al archivo .asp o a Global.asa para declarar la
biblioteca de tipos ADO:

<!--METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library"


TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}"-->

Si desea obtener más detalles acerca de cómo implementar las bibliotecas de tipos de
componentes, consulte la sección Utilizar constantes del tema Utilizar variables y constantes.

Además del comando INSERT de SQL, puede utilizar los comandos UPDATE y DELETE de SQL
para modificar y quitar información de la base de datos.

Con el comando UPDATE de SQL puede modificar los valores de los elementos de una tabla de la
base de datos. La siguiente secuencia de comandos usa el comando UPDATE para cambiar todos
los campos FirstName de la tabla Customers a Juan en todas las filas cuyo campo LastName
contenga el apellido Soto.

<%

Set cn = Server.CreateObject("ADODB.Connection")

cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\Datos\Empleados.mdb"

cn.Execute "UPDATE Customers SET FirstName = 'Juan' WHERE LastName =


'Soto' ",,adCmdText + adExecuteNoRecords

%>

Para quitar determinados registros de una tabla de la base de datos, utilice el comando DELETE
de SQL. La siguiente secuencia de comandos quita todas las filas de la tabla Customers cuyo
apellido sea Soto:

141
<%

Set cn = Server.CreateObject("ADODB.Connection")

cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\Datos\Empleados.mdb"

cn.Execute "DELETE FROM Customers WHERE LastName = 'Soto'",,adCmdText +


adExecuteNoRecords

%>

Nota Debe tener mucho cuidado al utilizar el comando DELETE de SQL. Un comando DELETE
que no vaya acompañado de una cláusula WHERE eliminará todas las filas de la tabla. Asegúrese
de incluir la cláusula WHERE de SQL, que especifica las filas exactas que se van a eliminar.

Utilizar el objeto Recordset para manipular los resultados

Para recuperar datos, examinar resultados y modificar su base de datos, ADO proporciona el
objeto Recordset. El objeto Recordset tiene las funciones necesarias para, dependiendo de las
restricciones de las consultas, recuperar y presentar un conjunto de filas, o registros, de una base
de datos. El objeto Recordset mantiene la posición de cada registro devuelto por la consulta, lo que
permite recorrer los resultados de uno en uno.

Recuperar un conjunto de registros

Las buenas aplicaciones de datos Web emplean el objeto Connection para establecer un vínculo, y
el objeto Recordset para manipular los datos devueltos. Al combinar las funciones especializadas
de ambos objetos puede desarrollar aplicaciones de bases de datos que realicen casi cualquier
tarea de tratamiento de datos. Por ejemplo, la siguiente secuencia de comandos del servidor utiliza
el objeto Recordset para ejecutar un comando SELECT de SQL. El comando SELECT recupera un
conjunto específico de información basándose en las restricciones de la consulta. La consulta
también contiene una cláusula WHERE de SQL, que se utiliza para establecer el criterio de
selección de la consulta. En este ejemplo, la cláusula WHERE limita la consulta a todos los
registros que contengan el apellido Soto en la tabla Customers de la base de datos.

<%

'Establece una conexión con un origen de datos.

strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\Datos\Empleados.mdb"

Set cn = Server.CreateObject("ADODB.Connection")

cnn.Open strConnectionString

'Crea una instancia de un objeto Recordset.

Set rsCustomers = Server.CreateObject("ADODB.Recordset")

'Abre un objeto Recordset con el método Open

142
'y utiliza la conexión establecida por el objeto Connection.

strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName =


'Soto' "

rstCustomers.Open strSQL, cnn

'Recorre el conjunto de los registros y presenta los resultados

'e incrementa la posición del registro con el método MoveNext.

Set objFirstName = rstCustomers("Nombre")

Set objLastName = rstCustomers("Apellido")

Do Until rstCustomers.EOF

Response.Write objFirstName & " " & objLastName & "<BR>"

rstCustomers.MoveNext

Loop

%>

Observe que en el ejemplo anterior, el objeto Connection estableció la conexión con la base de
datos y que el objeto Recordset utilizó la misma conexión para recuperar resultados de la base de
datos. Este método es útil cuando tenga que configurar con precisión la forma en que se establece
el vínculo con la base de datos. Por ejemplo, si necesitara especificar el tiempo de espera antes de
anular un intento de conexión, tendría que utilizar el objeto Connection para establecer dicha
propiedad. Sin embargo, si sólo desea establecer una conexión con las propiedades de conexión
predeterminadas de ADO, podría utilizar el método Open del objeto Recordset para establecer el
vínculo:

<%

strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\Datos\Empleados.mdb"

strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName =


'Soto' "

Set rsCustomers = Server.CreateObject("ADODB.Recordset")

'Abre una conexión con el método Open

'y utiliza la conexión establecida por el objeto Connection.

rstCustomers.Open strSQL, strConnectionString

'Recorre el conjunto de registros, presenta los resultados

143
'e incrementa la posición del registro con el método MoveNext.

Set objFirstName = rstCustomers("Nombre")

Set objLastName = rstCustomers("Apellido")

Do Until rstCustomers.EOF

Response.Write objFirstName & " " & objLastName & "<BR>"

rstCustomers.MoveNext

Loop

%>

Cuando establece una conexión con el método Open del objeto Recordset, está utilizando
implícitamente el objeto Connection para proteger el vínculo. Para obtener más información,
consulte la documentación acerca de Microsoft ActiveX Data Objects (ADO), disponible en el sitio
Web de Microsoft Universal Data Access en la dirección http://www.microsoft.com/data/.

Para mejorar de forma significativa el rendimiento de las aplicaciones ASP de base de datos,
piense en la posibilidad de cambiar el estado del conjunto de registros a Application. Para obtener
más información, consulte Guardar datos en la memoria caché.

A menudo resulta útil contar el número de registros que se devuelven en un conjunto de registros.
El método Open del objeto Recordset permite especificar un parámetro opcional, cursor, que
determina cómo recupera y recorre el conjunto de registros el proveedor subyacente. Al agregar el
parámetro de cursor adOpenKeyset a la instrucción que se utiliza para ejecutar la consulta, permite
que la aplicación cliente recorra todo el conjunto de registros. Como resultado, la aplicación puede
utilizar la propiedad RecordCount para calcular con precisión el número de registros del conjunto.
Vea el siguiente ejemplo:

<%

Set rsCustomers = Server.CreateObject("ADODB.Recordset")

rs.Open "SELECT * FROM NewOrders",


"Provider=Microsoft.Jet.OLEDB.3.51;Data
Source='C:\PedidosClientes\Pedidos.mdb'", adOpenKeyset, adLockOptimistic,
adCmdText

'Utiliza la propiedad RecordCount del objeto Recordset para realizar la


cuenta.

If rs.RecordCount >= 5 then

Response.Write "Recibimos estos " & rs.RecordCount & " nuevos


pedidos<BR>"

Do Until rs.EOF

144
Response.Write rs("NombreCliente") & " " & rs("ApellidoCliente") & "<BR>"

Response.Write rs("NumeroCuenta") & "<BR>"

Response.Write rs("Cantidad") & "<BR>"

Response.Write rs("FechaEntrega") & "<BR><BR>"

rs.MoveNext

Loop

Else

Response.Write "Hay menos de " & rs.RecordCount & " nuevos pedidos."

End If

rs.Close

%>

Combinar formularios HTML y el acceso a bases de datos

Las páginas Web que contienen formularios HTML pueden permitir que los usuarios consulten de
forma remota una base de datos y recuperen información concreta. Con ADO puede crear
secuencias de comandos sorprendentemente sencillas que recopilen información del formulario del
usuario, creen una consulta personalizada para la base de datos y devuelvan información al
usuario. Mediante el objeto Request de ASP puede recuperar la información escrita en los
formularios HTML e incorporar dicha información a sus instrucciones SQL. Por ejemplo, el
siguiente bloque de secuencia de comandos inserta en una tabla la información suministrada por
un formulario HTML. La secuencia de comandos recopila información del usuario con la colección
Form del objeto Request.

<%

'Abre una conexión mediante el objeto Connection. El objeto Command

'no tiene un método Open para establecer la conexión.

strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=D:\Catálogo\Semillas.mdb"

Set cn = Server.CreateObject("ADODB.Connection")

cnn.Open strConnectionString

'Crea una instancia del objeto Command

'y utiliza la propiedad ActiveConnection para adjuntar

'la conexión al objeto Command.

145
Set cm= Server.CreateObject("ADODB.Command")

Set cmn.ActiveConnection = cnn

'Define la consulta SQL.

cmn.CommandText = "INSERT INTO MySeedsTable (Type) VALUES (?)"

'Define la información de configuración de los parámetros de la consulta.

cmn.Parameters.Append cmn.CreateParameter("type",adVarChar, ,255)

'Asigna el valor de la entrada y ejecuta la actualización.

cmn("type") = Request.Form("SeedType")

cmn.Execute ,,adCmdText + adExecuteNoRecords

%>

Para obtener más información acerca de los formularios y el uso del objeto Request de ASP,
consulte Procesar los datos introducidos por el usuario.

Transferencia entre archivos .ASP

Para utilizar Response.Redirect para redirigir un explorador se necesita un viaje de ida y vuelta, lo
que significa que el servidor envía al explorador una respuesta HTTP en la que indica la ubicación
de la nueva dirección URL. El explorador abandona automáticamente la cola de la petición del
servidor y envía una nueva petición HTTP para la dirección URL. Después, el servidor agrega esta
petición a la cola de peticiones, junto con las peticiones que mientras tanto llegan desde otros
clientes. En un sitio Web con mucha carga, este sistema puede desperdiciar ancho de banda y
reducir el rendimiento del servidor, especialmente si se redirige el explorador a un archivo que se
encuentre en el mismo servidor.

Puede utilizar el método Server.Transfer para realizar la transferencia de un archivo .asp a otro que
se encuentre en el mismo servidor, en lugar del método Response.Redirect. Con Server.Transfer
puede transferir directamente las peticiones de archivos .asp sin necesidad de abandonar la cola
de peticiones, lo que elimina viajes de ida y vuelta.

Por ejemplo, la secuencia de comandos siguiente muestra cómo podría utilizar Server.Transfer
para saltar entre las páginas de una aplicación según la información de estado:

<%

If Session("blnSaleCompleted") Then

Server.Transfer("/Pedido/Gracias.asp")

Else

Server.Transfer("/Pedido/MasInfo.asp")

146
End if

%>

Server.Transfer envía peticiones desde un archivo .asp en ejecución a otro archivo. Durante la
transferencia, el archivo .asp que se pidió inicialmente finaliza inmediatamente la ejecución sin
vaciar el búfer de salir (para obtener más información, consulte la sección Almacenamiento en
búfer del contenido). La petición de información se pone a disposición del archivo de destino
cuando éste comienza la ejecución. Durante la ejecución, el archivo tiene acceso al mismo
conjunto de objetos intrínsecos (Request, Response, Server, Session y Application) que el archivo
que se pidió inicialmente.

También se puede utilizar Server.Transfer para realizar una transferencia entre archivos .asp que
se encuentren en diferentes aplicaciones. Sin embargo, al hacerlo el archivo se comportará como
si formara parte de la aplicación que inició la transferencia (es decir, el archivo sólo tendrá acceso
a las variables con alcance en la aplicación inicial, no en la aplicación en la que realmente reside el
archivo). Por ejemplo, si realiza una transferencia desde un archivo que se encuentra en la
aplicación Ventas a otro que se encuentra en Personal, la aplicación Ventas tomará prestado el
archivo de la aplicación Personal y lo ejecutará como si fuera parte de ella.

ASP proporciona también el comando Server.Execute que permite transferir un archivo, ejecutar el
contenido y volver al archivo que inició la transferencia. Si tiene conocimientos de VBScript, le
ayudará pensar en Server.Execute como análogo a una llamada a un procedimiento, con la
diferencia de que en lugar de ejecutar un procedimiento se ejecuta un archivo .asp completo.

Por ejemplo, la secuencia de comandos siguiente muestra cómo podría utilizar Server.Execute
para incluir archivos .asp de forma dinámica:

<%

If blnUseDHTML Then

Server.Execute("DHTML.asp")

Else

Server.Execute("HTML.asp")

End If

%>

Mientras el archivo de destino pertenezca a una aplicación del mismo servidor, la aplicación inicial
se transferirá a este archivo, ejecutará su contenido y continuará con la ejecución del archivo que
inició la transferencia. Igual que sucede con Server.Transfer, al ejecutar un archivo .asp éste se

147
comporta como si formara parte de la aplicación inicial. Sin embargo, Server.Execute, no funciona
cuando los servidores son distintos. Para obtener más información, consulte Server.Execute.

Enviar contenido al explorador

A medida que se procesa una secuencia de comandos ASP, el texto y los gráficos que no se
encuentren entre delimitadores ASP o etiquetas <SCRIPT> se devuelve directamente al
explorador. También puede enviar explícitamente contenido al explorador mediante el objeto
Response.

Enviar contenido

Para enviar contenido al explorador desde delimitadores ASP o desde un procedimiento, utilice el
método Write del objeto Response. Por ejemplo, la instrucción siguiente envía un saludo diferente
al usuario dependiendo de si el usuario ha visitado la página con anterioridad o no:

<%

If blnFirstTime Then

Response.Write "<H3 ALIGN=CENTER>Reciba nuestra bienvenida a la página de


introducción</H3>"

Else

Response.Write "<H3 ALIGN=CENTER>Gracias por volver a la página de


introducción</H3>"

End If

%>

Fuera de un procedimiento, no tiene que utilizar Response.Write para devolver contenido al


usuario. El contenido que no se encuentra dentro de delimitadores de secuencia de comandos se
envía directamente al explorador, que da formato y presenta este contenido. Por ejemplo, la
secuencia de comandos siguiente produce el mismo resultado que la secuencia de comandos
anterior:

<H3 ALIGN=CENTER>

<% If blnFirstTime Then %>

Reciba nuestra bienvenida a la página de introducción.

<% Else %>

Gracias por volver a la página de introducción.

<%End If %>

</H3>

148
Intercale secuencias de comandos y código HTML cuando tenga que devolver el resultado una vez
o cuando sea más cómodo agregar instrucciones a texto HTML existente. Utilice Response.Write
cuando no desee dividir una instrucción con delimitadores o cuando desee generar la cadena de
texto que vaya a devolver al explorador. Por ejemplo, podría generar una cadena de texto que
creara una fila de una tabla con los valores enviados por un formulario HTML:

Response.Write "<TR><TD>" & Request.Form("Nombre") _

& "</TD><TD>" & Request.Form("Apellido") & "</TD></TR>"

Request.Form devuelve los valores enviados por un formulario HTML


(consulte Procesar los datos introducidos por el usuario).

El carácter & es el carácter de continuación de cadenas de VBScript. El carácter de subrayado (_)


es el carácter de continuación de línea de VBScript.

Secuencias de comandos sencillas

La siguiente secuencia de comandos ilustra las técnicas básicas que se utilizan en las secuencias
de comandos ASP. Si no tiene experiencia en el desarrollo de aplicaciones o nunca ha escrito
secuencias de comandos, éste es un buen lugar para empezar.

Elija un ejemplo en la siguiente lista:

• Variables: Muestra cómo crear y manipular variables en una secuencia de comandos ASP.
• Bucles: Proporciona un ejemplo de las tres construcciones más comunes para crear
bucles, For ... Next, Do ... Loop y While ... Wend.
• Operadores condicionales: Ilustra el uso de los operadores condicionales, como If ... Then,
en las secuencias de comandos ASP.
• Matrices: Muestra cómo crear, administrar y tener acceso a matrices.
• Archivos de inclusión del servidor: Muestra el uso de los archivos de inclusión del servidor.
• Funciones y procedimientos: Muestra cómo crear y utilizar funciones y procedimientos en
una secuencia de comandos ASP.

Variables

Introducción

Todas las aplicaciones escritas a lo largo de la historia, independientemente del lenguaje de


programación empleado, han utilizado variables de algún tipo y las secuencias de comandos ASP
no son una excepción. Tanto VBScript como JScript permiten crear y administrar variables de
forma fácil y sencilla.

Cada lenguaje realiza de forma diferente la declaración de variables. JScript y VBScript son
bastante flexibles en lo que respecta a las variables y su declaración. En VBScript, cualquier
variable se considera automáticamente de tipo Variant si se declara inicialmente con la instrucción
Dim. A cada variable se le asigna un subtipo, como Numeric y Array. JScript es parecido; la
variable se declara inicialmente con la instrucción var. En general, ambos lenguajes tienden a
realizar automáticamente gran parte de la administración de tipos de datos, incluida la conversión
de tipos. De hecho, ni siquiera es necesario emplear las instrucciones Dim o var para utilizar una
nueva variable; en sus respectivos lenguajes son opcionales.

Paseo por el código

149
Este ejemplo declara varios tipos diferentes de variables, realiza algunas operaciones sencillas en
ellas y las muestra al explorador cliente con los delimitadores especiales de secuencias de
comandos <% = ...%>. Se asigna un entero a la variable intVariable, se suma a sí mismo y se
envía el resultado al explorador cliente. A la variable StrVariable se le asigna el nombre, se agrega
a Soto y se envía al explorador cliente. Del mismo modo se declaran o crean, inicializan, manipulan
y muestran los valores booleanos y las fechas.

Observaciones

El último paso de la demostración de la variable de fecha es especialmente interesante. En


VBScript, primero se asigna la variable a una cadena de fecha literal y después se muestra.
Después se restablece y se asigna el valor devuelto por la función Now de VBScript, que devuelve
la hora actual del sistema. El ejemplo de JScript utiliza la función Date de JScript para establecer el
literal inicial, para lo que pasa parámetros a la función, y establecer después la fecha actual del
sistema en la variable, sin pasar parámetros a la función.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<HTML>

<HEAD>

<TITLE>Variable Sample</TITLE>

</HEAD>

<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">

<!-- Display header. -->

<FONT SIZE="4" FACE="ARIAL, HELVETICA">

<B>Variable Sample</B></FONT><BR>

<HR>

<H3>Integer Manipulation</H3>

<%

'Declare variable.

Dim intVar

'Assign the variable an integer value.

intVar = 5

%>

150
<P><%= intVar %> + <%= intVar %> = <%= intVar + intVar %></P>

<HR>

<H3>String Manipulation</H3>

<%

'Declare variable.

Dim strVar

'Assign the variable a string value.

strVar = "Jemearl"

%>

<P>This example was done by <%= strVar + " Smith" %></P>

<HR>

<H3>Boolean Manipulation</H3>

<%

'Declare variable.

Dim blnVar

'Assign the variable a Boolean value.

blnVar = true

'Output message based on value.

If (blnVar) Then

Response.Write "<P>The Boolean value is True.</P>"

Else

Response.Write "<P>The Boolean value is False.</P>"

End If

%>

<HR>

<H3>Date and Time</H3>

151
<%

'Declare variable.

Dim dtmVar

'Assign the variable a value.

dtmVar = #08 / 27 / 97 5:11:42pm#

%>

<P>The date and time is <%= dtmVar %>

<%

'Set the variable to the web server date and time.

dtmVar = Now()

%>

<P>The <STRONG>system</strong> date and time is <%= dtmVar %></P>

</BODY>

</HTML>

Bucles

Introducción

Los bucles representan uno de los mecanismos más importantes de control de flujo en un lenguaje
de programación. Las construcciones en bucle proporcionan la base de cualquier aplicación que
deba realizar una tarea de forma repetitiva, como sumar 1 a una variable, leer un archivo de texto o
procesar y enviar un mensaje de correo electrónico.

Paseo por el código

VBScript y JScript proporcionan varios mecanismos para realizar bucles. Este ejemplo demuestra
las tres instrucciones más comunes para realizar bucles, For ... Next, Do ... Loop y While ... Wend.
Estas tres instrucciones son ligeramente diferentes y la situación indicará cuál de las tres es la más
indicada. Sin embargo, para este ejemplo, cada tipo de instrucción de bucle se utiliza para realizar
la misma tarea: imprimir un saludo cinco veces, cada una de ellas con una fuente mayor. En cada
instrucción de bucle se inicializa la variable i y se define la condición de prueba, de forma que i
nunca sea mayor que 5. La variable se incrementa en 1 unidad en cada iteración del bucle.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<HTML>

152
<HEAD>

<TITLE>Looping</TITLE>

</HEAD>

<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">

<!-- Display header. -->

<FONT SIZE="4" FACE="ARIAL, HELVETICA">

<B>Looping with ASP</B></FONT><BR>

<HR SIZE="1" COLOR="#000000">

<!-- Looping with a For loop. -->

<%

Dim intCounter

For intCounter = 1 to 5 %>

<FONT SIZE=<% = intCounter %>>

Hello World with a For Loop!<BR>

</FONT>

<% next %>

<HR>

<!-- Looping with a While...Wend loop. -->

<%

intCounter = 1

While(intCounter < 6) %>

<FONT SIZE=<% = intCounter %>>

Hello World with a While Loop!<BR>

</FONT>

<% intCounter = intCounter + 1 %>

<% wend %>

153
<HR>

<!-- Looping with a Do...While loop. -->

<%

intCounter = 1

Do While(intCounter < 6) %>

<FONT SIZE=<% =intCounter %>>

Hello World with a Do...While Loop!<BR>

</FONT>

<% intCounter = intCounter+1 %>

<% loop %>

</BODY>

</HTML>

Operadores condicionales

Introducción

Los operadores condicionales, junto con las variables y las construcciones de bucle, forman los
pilares básicos de los lenguajes de programación y, por tanto, de las aplicaciones. Las aplicaciones
basadas en Web que se implementan mediante secuencias de comandos ASP pueden aprovechar
el control de flujo que proporcionan los operadores condicionales, así como la interactividad y la
sofisticación de HTML.

Paseo por el código

Este ejemplo demuestra las instrucciones If ... Then o if ... else en VBScript y JScript, así como las
instrucciones Select ... Case y switch ... case, más complejas. La demostración de cada una de
estas instrucciones realiza la misma tarea: enviar una página al explorador cliente con la fecha y la
hora actuales y un saludo. El texto del saludo será "Buenos días" o "Buenas tardes", dependiendo
de si en el reloj del sistema aparece a.m. o p.m.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<HTML>

<HEAD>

<TITLE>Conditional Operator Sample</TITLE>

154
</HEAD>

<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">

<!-- Display header. -->

<FONT SIZE="4" FACE="ARIAL, HELVETICA">

<B>Conditional Operator Sample</B></FONT><BR>

<HR SIZE="1" COLOR="#000000">

<!-- If...Then example -->

<%

Dim varDate

varDate = Date()

%>

<P>The date is: <%= varDate %></P>

<%

'Select Case statement to display a message based on the day of the


month.

Select Case Day(varDate)

Case 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Response.Write("<P>It's the beginning of the month.</P>")

Case 11, 12, 13, 14, 15, 16, 17, 18, 19, 20

Response.Write("<P>It's the middle of the month.</P>")

Case Else

Response.Write("<P>It's the end of the month.</P>")

End Select

%>

<P>The time is: <%= Time %></P>

<%

155
'Check for AM/PM, and output appropriate message.

If (Right(Time,2)="AM") Then

Response.Write("<P>Good Morning</P>")

Else

Response.Write("<P>Good Evening</P>") #9; #9; #9; End If

%>

</BODY>

</HTML>

Funciones y procedimientos

Introducción

Las funciones y los procedimientos proporcionan un método para evitar tener que escribir varias
veces un mismo bloque de código cada vez que desee realizar una tarea determinada. Tanto
VBScript como JScript permiten llamar a una función o a un procedimiento desde cualquier lugar
de una secuencia de comandos. Este ejemplo demuestra cómo puede crear y utilizar estas
herramientas en secuencias de comandos ASP.

Si no tiene ninguna función en la página ASP, el motor ASP se limita a procesar el archivo
completo, de principio a fin, cada vez que lo pide un explorador cliente. Sin embargo, las funciones
y los procedimientos se ejecutan sólo cuando se les llama, no con el resto del código.

En VBScript o JScript las funciones y los procedimientos se indican mediante la instrucción


Function. Además, VBScript establece una diferencia entre una función que devuelve un valor y
otra que no lo hace; la primera de ellas se indica con la instrucción Sub, que la identifica como una
subrutina.

Paseo por el código

Este ejemplo define una función, PrintOutMsg, que toma como parámetros un mensaje y un
número que especifica cuántas veces se escribirá el mensaje en el explorador cliente mediante el
método Response.Write. Para este ejemplo, la función se limita a devolver al explorador cliente el
número de veces que se imprimió el mensaje.

Observaciones

Es importante tener en cuenta el atributo RUNAT de la etiqueta <SCRIPT>. SI no se incluye, ASP


asumirá que se trata de una secuencia de comandos del cliente y devolverá el código al explorador
para que lo procese. Esto haría que ASP no reconociera la llamada a la función PrintOutMsg,
devolviera un error y anulara la ejecución.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

156
<SCRIPT LANGUAGE=VBScript RUNAT=Server>

'Define Server Side Script Function.

Function PrintOutMsg(strMsg, intCount)

Dim i

'Output Message count times.

For i = 1 to intCount

Response.Write(strMsg & "<BR>")

Next

'Return number of iterations.

PrintOutMsg = intCount

End Function

</SCRIPT>

<HTML>

<HEAD>

<TITLE>Functions</TITLE>

</HEAD>

<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">

<!-- Display header. -->

<FONT SIZE="4" FACE="ARIAL, HELVETICA">

<B>Server Side Functions</B></FONT><BR>

<P>

The function "PrintOutMsg" prints out a specific message a set number of


times.<P>

<%

'Store number of times function printed message.

157
Dim intTimes

'Call function.

intTimes = PrintOutMsg("This is a function test!", 4)

'Output the function return value.

Response.Write("<p>The function printed out the message " & intTimes & "
times.")

%>

</BODY>

</HTML>

Datos introducidos por el usuario en un formulario con POST

Introducción

Probablemente, la forma más básica de interactividad Web es el formulario HTML. Es importante


tener en cuenta que ASP no sustituye a los formularios, sino que los mejora y hace que sea más
fácil implementarlos y administrarlos.

La etiqueta HTML <FORM> especifica qué método utilizará el formulario para comunicar la
información a la secuencia de comandos que la procesará. El atributo del método POST indica que
la información del formulario pasará a través de una conexión HTTP independiente a la secuencia
de comandos o al programa que la procesará. La secuencia de comandos o el programa pueden
analizar la información y realizar cualquier tarea que sea necesaria, y devolver el resultado al
explorador cliente.

Paseo por el código

Este ejemplo muestra cómo implementar un formulario sencillo mediante el atributo del método
POST de HTTP, así como una de las principales ventajas de la creación de formularios mediante
ASP: la posibilidad de combinar el formulario y el código de proceso real en un mismo archivo. Este
ejemplo crea un pequeño formulario con dos cuadros de entrada de texto, uno para el nombre del
usuario (fname) y otro para el apellido (lname). Para obtener el valor de las variables fname y
lname en la petición se tiene acceso a la colección Request.Forms y después se muestran los
resultados en la parte inferior de la página.

La primera vez que se ejecuta la secuencia de comandos no aparece ningún texto debajo de la
línea horizontal. Esto se debe a que no había información disponible para pasarla a la secuencia
de comandos cuando se inició y ASP pasa por alto las búsquedas de Request.Forms si no existe
información. Sin embargo, si hace clic en el botón Enviar, se cargará de nuevo la página y la
secuencia de comandos ya dispondrá de la información que escribió en los cuadros de texto.

<%@ Language = VBScript %>

<% Option Explicit %>

158
<HTML>

<HEAD>

<TITLE>Form Posting</TITLE>

</HEAD>

<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">

<!-- Display header. -->

<FONT SIZE="4" FACE="ARIAL, HELVETICA">

<B>Form Posting</B></FONT><BR>

<HR>

<P>This page will take the information entered in the form fields, and
use the POST method to send the data to an ASP page.

<FORM NAME=Form1 METHOD=Post ACTION="Form_VBScript.asp">

First Name: <INPUT TYPE=Text NAME=fname><P>

Last Name: <INPUT TYPE=Text NAME=lname><P>

<INPUT TYPE=Submit VALUE="Submit">

</FORM>

<HR>

<% Response.Write Request.form("fname")%> <BR>

<% Response.Write Request.form("lname")%> <BR>

</BODY>

</HTML>

Llenar los campos

Introducción

Puede utilizar formularios para recopilar datos de los usuarios, pero también puede utilizarlos para
mostrar información. Por ejemplo, si un explorador cliente tiene acceso al motor de búsqueda de su
directorio de teléfonos, querrá mostrar los resultados de la búsqueda. La secuencia de comandos
de búsqueda (que también puede implementar mediante ASP) acepta los datos introducidos por el
usuario, tiene acceso a la base de datos y envía el resultado al formulario de presentación en una

159
cadena de consulta. Este ejemplo es una demostración sencilla de cuál sería la apariencia del
formulario.

Paseo por el código

Para este ejemplo, los datos se incluyen en el código de la secuencia de comandos pero,
obviamente, la información podría provenir de un formulario interactivo, de una base de datos o de
un archivo de texto. Al iniciarse el ejemplo se inicializan las variables. Después, crea un formulario
con las etiquetas HTML <FORM> y define cuatro cuadros de texto. Por último, con los
delimitadores de secuencias de comandos del servidor <%= ... %>, la secuencia de comandos
llena los cuadros de texto con los valores establecidos en la inicialización.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<%

'Create and set variables that will be used in populating 'the form. In a
typical application, these values would come from a database or text
file.

Dim strFirstName

Dim strLastName

Dim strAddress1

Dim strAddress2

Dim blnInfo

strFirstName = "John"

strLastName = "Doe"

strAddress1 = "1 Main Street"

strAddress2 = "Nowhere ZA, 12345"

%>

<HTML>

<HEAD>

<TITLE>PopulateForm Sample</TITLE>

</HEAD>

<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">

160
<!-- Display header. -->

<FONT SIZE="4" FACE="ARIAL, HELVETICA">

<B>PopulateForm Sample</B></FONT><BR>

<HR SIZE="1" COLOR="#000000">

<FORM ACTION="">

<!-- Use ASP variables to fill out the form. -->

<P>First Name: <INPUT TYPE="TEXT" NAME="FNAME" VALUE="<%= strFirstName


%>"></P>

<P>Last Name: <INPUT TYPE="TEXT" NAME="LNAME" VALUE="<%= strLastName


%>"></P>

<P>Street: <INPUT TYPE="TEXT" NAME="STREET" VALUE="<%=


strAddress1%>"></P>

<P>City State, Zip: <INPUT TYPE="TEXT" NAME="FNAME" VALUE="<%=


strAddress2 %>"></P>

</BODY>

</HTML>

Conectividad con bases de datos

Si va a crear una aplicación basada en Web, lo más probable es que tenga formularios.
Posiblemente, también tendrá que conectarla de alguna forma con una base de datos. ActiveX®
Data Objects (ADO) proporciona un conjunto de eficaces herramientas que le permitirán tener
acceso a orígenes de datos y manipularlos.

Los ejemplos de esta sección ilustran las técnicas necesarias para utilizar ADO de forma efectiva y
cómo puede utilizar mejor estas funciones en una aplicación basada en Web.

• Consulta sencilla: Muestra cómo utilizar ADO y ASP para realizar consultas sencillas en
una base de datos.
• Limitar los resultados de una consulta: Muestra cómo es posible utilizar ASP y ADO en las
secuencias de comandos para limitar el número de filas devueltas en un conjunto de
registros.
• Consulta desplazable: Muestra cómo realizar con ADO una consulta desplazable
multidireccional.
• Agregar o eliminar registros: Presenta las técnicas necesarias para agregar y eliminar
registros de un origen de datos mediante ASP y ADO.
• Actualizar registros: Muestra cómo utilizar ADO en una aplicación para actualizar los
registros existentes.
• Ejecutar procedimientos almacenados: Muestra cómo utilizar ADO con las secuencias de
comandos ASP para ejecutar procedimientos almacenados de la base de datos.

161
Para obtener más información acerca de ADO y de las herramientas de acceso a datos de
Microsoft en general, consulte la documentación de Microsoft Data Access.

Consulta sencilla

Introducción

Aunque una base de datos puede ser un sistema muy complicado y las herramientas de acceso a
datos deben ser eficaces y sensibles, es igualmente importante que las tareas sencillas de acceso
a bases de datos sean fáciles de realizar. Este ejemplo demuestra cómo ADO proporciona un
método sencillo para realizar este tipo de tareas.

Paseo por el código

El objetivo de esta aplicación de ejemplo es obtener un pequeño conjunto de registros de una base
de datos de Microsoft® Access e imprimir el resultado. El primer paso consiste en crear una
instancia del objeto Connection mediante el método Server.CreateObject. El ejemplo utiliza la
instancia del objeto Connection para abrir el proveedor de datos OLE DB y, después, para ejecutar
un comando SELECT de SQL y así obtener todos los registros de la tabla Autores. Para terminar,
la secuencia de comandos recorre la colección del conjunto de registros obtenido y muestra los
resultados. Después se cierran el conjunto de registros y la conexión con el origen de datos OLE
DB.

Importante OLE DB debe estar correctamente configurado en el servidor para que este ejemplo
funcione correctamente.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<HTML>

<HEAD>

<TITLE>Simple ADO Query</TITLE>

</HEAD>

<BODY BGCOLOR="White" topmargin="10" leftmargin="10">

<!-- Display Header -->

<font size="4" face="Arial, Helvetica">

<b>Simple ADO Query with ASP</b></font><br>

<hr size="1" color="#000000">

Contacts within the Authors Database:<br><br>

<%

162
Dim oConn

Dim oRs

Dim filePath

Dim Index

' Map authors database to physical path

filePath = Server.MapPath("authors.mdb")

' Create ADO Connection Component to connect

' with sample database

Set oConn = Server.CreateObject("ADODB.Connection")

oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath

' Execute a SQL query and store the results

' within recordset

Set oRs = oConn.Execute("SELECT * From Authors")

%>

<TABLE border = 1>

<%

Do while (Not oRs.eof) %>

<tr>

<% For Index=0 to (oRs.fields.count-1) %>

<TD VAlign=top><% = oRs(Index)%></TD>

<% Next %>

</tr>

<% oRs.MoveNext

Loop

%>

</TABLE>

163
<%

oRs.close

oConn.close

%>

</BODY>

</HTML>

Agregar o eliminar registros

Introducción

Este ejemplo muestra las técnicas que necesita conocer para utilizar ASP y ADO con el fin de
agregar y eliminar registros de una base de datos.

Paseo por el código

Primero se utiliza CreateObject para crear una instancia del objeto Connection, que a su vez se
utiliza para abrir una conexión con el proveedor de datos OLE DB. Se utiliza de nuevo
CreateObject para crear un objeto Recordset vacío. Se configura la propiedad ActiveConnection
para hacer referencia al nuevo objeto Connection.

Aunque el objeto Recordset de ADO proporciona el método AddNew para agregar nuevos registros
a una base de datos, puede que la escalabilidad mejore si envía comandos INSERT de SQL
directamente al motor de base de datos. Este ejemplo utiliza el comando Recordset.Execute, junto
con la cadena de comandos apropiada de SQL, para insertar información acerca de un nuevo
autor.

En este momento se crea otra instancia del objeto Recordset y se abre con otro comando SQL. Se
selecciona el registro recién agregado y se elimina, para lo cual se pasa el comando DELETE de
SQL directamente al motor de base de datos. Por último, finaliza la secuencia de comandos.

Importante OLE DB debe estar correctamente configurado en el servidor para que este ejemplo
funcione correctamente.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<% Response.Expires= -1 %>

<!--METADATA TYPE="typelib"

uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<HTML>

<HEAD>

164
<TITLE>Add/Delete Database Sample</TITLE>

</HEAD>

<BODY BGCOLOR="White" topmargin="10" leftmargin="10">

<!-- Display Header -->

<font size="4" face="Arial, Helvetica">

<b>Add/Delete Database Sample</b></font><br>

<hr size="1" color="#000000">

<%

Dim oConn

Dim oRs

Dim filePath

' Map authors database to physical path

filePath = Server.MapPath("authors.mdb")

' Create ADO Connection Component to connect with sample database

Set oConn = Server.CreateObject("ADODB.Connection")

oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath

' To add, delete and update recordset, it is recommended to use

' direct SQL statement instead of ADO methods.

oConn.Execute "insert into authors (author, YearBorn) values ('Paul


Enfield', 1967)"

' Output Result

Set oRs = oConn.Execute (" select * from authors where Author= 'Paul
Enfield' and YearBorn =1967 " )

Response.Write("<p>Inserted Author: " & oRs("Author") & "," &


oRs("YearBorn"))

' Close Recordset

165
oRs.Close

Set oRs= Nothing

' Delete the inserted record

oConn.Execute "Delete From authors where author='Paul Enfield' and


YearBorn = 1967 "

' Output Status Result

Response.Write("<p>Deleted Author: Paul Enfield, 1967")

%>

</BODY>

</HTML>

Actualizar registros

Introducción

Este ejemplo muestra cómo utilizar ADO en una aplicación para actualizar los registros existentes.

Paseo por el código

Primero se utiliza CreateObject para crear una instancia del objeto Connection, que a su vez se
utiliza para abrir una conexión con el proveedor de datos OLE DB. Se utiliza de nuevo
CreateObject para crear un objeto Recordset vacío. Se configura la propiedad ActiveConnection
para hacer referencia al nuevo objeto Connection.

Después se configura el nuevo conjunto de registros. El método Recordset.Execute utiliza como


parámetro una cadena de comandos SQL. Este ejemplo utiliza una cadena de comandos UPDATE
de SQL para realizar la actualización en los registros adecuados de la base de datos.

<%@ LANGUAGE = VBScript %>

<% Option Explicit %>

<!--METADATA TYPE="typelib"

uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<HTML>

<HEAD>

<TITLE>Update Database</TITLE>

</HEAD>

166
<BODY BGCOLOR="White" topmargin="10" leftmargin="10">

<!-- Display Header -->

<font size="4" face="Arial, Helvetica">

<b>Update Database</b></font><br>

<hr size="1" color="#000000">

<%

Dim oConn ' object for ADODB.Connection obj

Dim oRs ' object for output recordset object

Dim filePath ' Directory of authors.mdb file

' Map authors database to physical path

filePath = Server.MapPath("authors.mdb")

' Create ADO Connection Component to connect with sample database

Set oConn = Server.CreateObject("ADODB.Connection")

oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath

' To add, delete and update recordset, it is recommended to use

' direct SQL statement instead of ADO methods.

oConn.Execute "Update Authors Set Author ='Scott Clinton'" _

& "where Author='Scott Guthrie' "

Set oRs = oConn.Execute ( "select * from Authors where author" _

& "= 'Scott Clinton'" )

%>

Changed Author: <%= oRs("Author") %>, <%= oRs("Yearborn") %> <P>

<%

oConn.Execute "Update Authors Set Author ='Scott Guthrie'" _

& "where Author='Scott Clinton' "

Set oRs = oConn.Execute ( "select * from Authors where author" _

167
& "= 'Scott Guthrie'" )

%>

Changed Author: <%= oRs("Author") %>, <%= oRs("Yearborn") %>

</BODY>

</HTML>

MapPath

El método MapPath asigna al directorio físico correspondiente del servidor la ruta virtual o relativa
especificada.

Sintaxis

Server.MapPath( Ruta )

Parámetros

Ruta

Especifica la ruta virtual o relativa que se asignará a un directorio físico. Si Ruta comienza con una
barra diagonal (/) o con una barra diagonal inversa (\), el método MapPath devuelve la ruta como si
Ruta fuera una ruta virtual completa. Si Ruta no comienza con una barra diagonal, el método
MapPath devuelve una ruta relativa al directorio del archivo .asp que se procesa.

Observaciones

El método MapPath no comprueba si la ruta que devuelve existe en el servidor o si es válida.

Como el método MapPath asigna la ruta independientemente de si los directorios especificados


existen o no, puede utilizarlo para asignar una ruta a una estructura física de directorios y,
después, pasarla a un componente que cree en el servidor el directorio o el archivo especificado.

Puede utilizar la sintaxis de ruta relativa para el parámetro Ruta si el valor de la propiedad
AspEnableParentPaths es TRUE (que es el valor predeterminado). Si le preocupa permitir que las
secuencias de comandos tengan acceso a la estructura física de directorios, puede deshabilitar
esta característica si asigna el valor FALSE a la propiedad AspEnableParentPaths. Para ello puede
utilizar el complemento Servicios de Internet Information Server o una secuencia de comandos.

Ejemplo

Para los siguientes ejemplos, el archivo data.txt se encuentra en el directorio


C:\Inetpub\Wwwroot\Script, al igual que el archivo test.asp, que contiene las siguientes secuencias
de comandos. El directorio C:\Inetpub\Wwwroot se establece como directorio particular del
servidor.

El siguiente ejemplo utiliza la variable de servidor PATH_INFO para asignar la ruta física al archivo
actual. La siguiente secuencia de comandos

168
<%= server.mappath(Request.ServerVariables("PATH_INFO"))%><BR>

produce el resultado

c:\inetpub\wwwroot\script\test.asp<BR>

Como los parámetros de la ruta de los siguientes ejemplos no empiezan con un carácter de barra
diagonal, se asignan de forma relativa al directorio actual, en este caso C:\Inetpub\Wwwroot\Script.
Las siguientes secuencias de comandos

<%= server.mappath("data.txt")%><BR>

<%= server.mappath("script/data.txt")%><BR>

producen el siguiente resultado

c:\inetpub\wwwroot\script\data.txt<BR>

c:\inetpub\wwwroot\script\script\data.txt<BR>

Los dos ejemplos siguientes utilizan el carácter de barra diagonal para especificar que la ruta que
se obtiene debe buscarse como ruta virtual completa del servidor. Las siguientes secuencias de
comandos

<%= server.mappath("/script/data.txt")%><BR>

<%= server.mappath("\script")%><BR>

producen el siguiente resultado

c:\inetpub\wwwroot\script\data.txt<BR>

c:\inetpub\wwwroot\script<BR>

Los siguientes ejemplos muestran cómo puede utilizar una barra diagonal (/) o una barra diagonal
inversa (\) para obtener la ruta física al directorio particular. Las siguientes secuencias de
comandos

<%= server.mappath("/")%><BR>

<%= server.mappath("\")%><BR>

producen el siguiente resultado

c:\inetpub\wwwroot<BR>

c:\inetpub\wwwroot<BR>

169
Curso de CGI

INTRODUCCIÓN

El CGI (Common Gateway Interface) es un estandar para comunicar aplicaciones externas con los
servidores de información, tales como servidores HTTP o Web. Un documento en HTML que el
daemon del Web se trae es estático, es decir, se mantiene constante: un fichero de texto que no
cambia. Un programa CGI, por otro lado es ejecutado en tiempo real, así que puede generar
información dinámica.

Por ejemplo, supongamos que quieres enganchar tu base de datos de Unix al WWW, para permitir
a gente de todo el mundo consultarla. Básicamente se necesitará un programa CGI que el daemon
del Web ejecutará para transmitir la información al gestor de base de datos, y recibir los resultados
para presentarselos al cliente. Este es un ejemplo de pasarela (gateway), y es lo que CGI,
actualmente, tiene en sus orígenes.

El ejemplo de la base de datos es una idea sencilla, pero la mayoría de las veces dificil de
implementar. Realmente no hay límite con lo que tu quieras enganchar al Web. La única cosa que
debes recordar es que haga lo que haga tu progrma CGI, no deberá tardar mucho tiempo en
procesar. De otra manera, el usuario estaría esperando con su navegador a que algo pase.

Especificaciones

Como un programa CGI es un ejecutable, es equivalente a dejar a el mundo ejecutar un programa


en tu sistema, que no es lo mas seguro a hacer. Por ello existen una serie de precauciones de
seguridad que son necesarias de implementar cuando se usan programas CGI. Probablemente la
que afectará al usuario típico del Web, es que hecho de que los programas CGI necesitan residir
en un directorio especial, así el servidor sabe que tiene que ejecutarlo, en vez de simplemente
mostrarlo por pantalla. Este directorio está generalmente bajo el control del webmaster,
prohibiendo al usuario medio crear programas CGI. Hay otros métodos para permitir el accesos a
scripts CGI, pero depende del webmaster que se te de esta posibilidad. Así que deberás contactar
con tu webmaster para consultar la factibilidad de permitirte un acceso a los CGI.

Si dispones de una versión del servidor HTTPd NCSA, verás un directorio denominado /cgi-bin.
Este es el directorio especial antes mencionado, donde todos los programas CGI residen. Un
programa CGI se puede escribir en cualquier lenguaje que permita ser ejecutado en el sistema,
como:

C/C++

Fortran

PERL

TCL

Algún Shell de Unix

Visual Basic.

170
AppleScript

Simplemente depende de lo que tengas en tu sistema. Si usas un lenguaje de programación como


C o Fortran, como ya sabrás, debes compilar el programa antes de poder ejecutarlo. Si miras en el
directorio /cgi-src, encontrarás el código fuente de algunos programas CGI del directorio /cgi-bin.
Pero, si usas alguno de los lenguajes in terpretados, como PERL, TCL, o un shell de Unix, el script
simplemente necesita residir en el directorio /cgi-bin, ya que no tiene un código fuente asociado.
Mucha gente prefiere escribir scripts CGI en vez de programas, ya que son más fáciles de depurar,
modificar y mantener que un programa típico compilado.

¿Qué es el directorio cgi-bin?

Este es un directorio especial, que contiene los scripts, configurado dentro del servidor http. El
servidor conoce que este directorio contiene ejecutables que deberán ser ejecutados y su salida
deberá ser enviada al navegador del cliente. No se puede simplemente crear un directorio cgi-bin,
el administrador del servidor deberá configurarlo para su uso. Si no está configurado, los scripst
serán cargados como simples ficheros de texto.

Algunos servidores están configurados de tal manera que los ficheros con una determinada
extensión (generalmente .cgi) son reconocidos como scripts y serán ejecutados como si estuvieran
en un directorio cgi-bin.

Nota: No deberemos confundirlo con html analizado (generalmente .shtml)

La configuración de los directorios, o de la extensión mencionada antes, depende únicamente del


servidor. Comprueba la documentación sobre tu servidor, o pregunta a otro usuario que también lo
use.

¿Qué parte es Perl, y qué parte es html?

El formulario que se presenta al usuario está escrito en html, y este llama al script en el servidor
escrito en perl . El script devolverá en la mayoría de los casos código html para presentar al
usuario.

VARIABLES DE ENTORNO EN CGI

El servidor usa tanto de líneas de comando, como variables de entorno para pasar los datos del
servidor al script.

Estas variables de entorno se activan cuando el programa ejecuta el programa cgi.

Especificación

Las siguientes variables no dependen de la información enviada y son activadas en todos los
casos:

SERVER_SOFTWARE

Devuelve el nombre y la versión del software del servidor de información que contesta la petición
de usuario (y ejecuta el programa cgi).

Formato: nombre/versión.

171
SERVER_NAME

Devuelve nombre de host del servidor, el alias DNS, o la dirección IP como aparecería en las URL
autoreferenciadas.

GATEWAY_INTERFACE

Devuelve la revisión de la especificación CGI con que el servidor puede trabajar.

Formato: CGI/revisión.

Las siguientes variables de entorno son específicas de la petición de usuario, y es el programa del
gateway el que las da el valor:

SERVER_PROTOCOL

Da el nombre y revisión del protocolo de información con el que la peticion de usuario viene.
Formato: protocolo/revisión.

SERVER_PORT

Devuelve el número de puerto por el cual fue enviada la petición.

REQUEST_METHOD.

Devuelve el método por el cual la petición fue enviada. Para HTTP serán "GET", "HEAD", "POST",
etc.

PATH_INFO

La información extra sobre el path, tal como es dada por el cliente. En otras palabras, podemos
acceder a los scripts por su pathname virtual, seguido de alguna información extra. Esa
información extra es enviada como PATH_INFO. La información será decodificada por el servidor
si viene de una URL antes de pasarla al script CGI.

PATH_TRANSLATED

El servidor proporciona una versión traducida del PATH_INFO, que transforma el path virtual al
físico.

SCRIPT_NAME

Path virtual al script que va a ejecutar, usado para autoreferenciar URL.

QUERY_STRING

La información que sigue al signo ‘?’ en la URL que referencia al script. Es la información de la
pregunta. No deberá ser decodificada de ningún modo. Esta variable será activada cuando hay una
petición de información, sin hacer caso de la decodificación de la línea de comandos.

REMOTE_HOST

172
El nombre de host que realiza la petición. Si el servidor no posee esta información activará
REMOTE_ADDR y dejará esta desactivada.

REMOTE_ADDR

La dirección IP del host remoto que realiza la petición.

AUTH_TYPE

Si el servidor soporta autentificación de usuario , y el script está protegido, esta es el método de


autentificación específico del protocolo para validar el usuario.

REMOTE_USER

Si el servidor soporta autentificación de usuario , y el script está protegido, este será el nombre de
usuario con el que se ha autentificado.

REMOTE_IDENT.

Si el servidor HTTP soporta autentificación RFC 931 , entonces está variable se activará con el
nombre del usuario remo to obtenido por el servidor. Esta varible solo se utilizará durante el login.

CONTENT_TYPE

Para peticiones que tienen información añadida, como HTTP POST y PUT, este será el tipo de
datos contenido.

CONTENT_LENGTH

La longitud del contenido tal como es dado por el cliente. Además, las líneas de la cabecera
recibidas por el cliente, si las hay, son colocadas en el entorno con el prefijo HTTP_ seguido del
nombre de la cabecera. Cada carácter de el nombre de la cabecera se cambia por caracteres _. El
servidor puede excluir algunos caracteres que ya haya procesado, como la autorización.

El tipo de contenido y la longitud de este, pueden ver suprimidas sus cabeceras si al incluirlos se
excede el límite de entorno del sistema.

Un ejemplo de esto es la variable HTTP_ACCEPT que se definió en CGI/1.0.

Otro ejemplo es la cabecera USER_AGENT.

HTTP_ACCEPT

Los tipos MIME que el cliente aceptará, como son dados por las cabeceras HTTP.

Otros protocolos pueden ser necesarios para obtener esa información de algún otro lugar.

Cada elemento de esta lista deberá estar separado por comas por la especificación HTTP.

Formato: tipo/subtipo, tipo/subtipo

173
HTTP_USER_AGENT

El navegador que el cliente usa para mandar la petición.

Formato general: software/versión librería/versión..

LEYENDO EL FORMULARIO DE ENTRADA DE USUARIO

Cuando el usuario envía el formulario, el script recibe los datos como pares nombre-valor.

Los nombres son lo que definimos en las etiquetas INPUT (o las etiquetas SELECT o TEXTAREA),
y los valores aquello que el usuario haya escrito o seleccionado. (Los usuarios también pueden
enviar ficheros con los formularios, pero no nos ocuparemos de ello.)

Estos pares nombre-valor llegan como una larga cadena que necesitamos formatear. No es muy
complicado, hay una gran cantidad de rutinas que lo hacen por tí. En el directorio CGI de Yahoo
encontrarás unas cuantas en varios lenguajes.

Si aun así prefiere hacerlo usted mismo, aquí esta el formato de la cadena:

"nombre1=valor1&nombre2=valor2&nombre3=valor3"

Así que sólo hay que dividir donde están los signos ‘&’ y ‘=’, y luego hacer dos cosas a cada
nombre y valor:

1.Convertir todos los signos ‘+’ a espacios.

2.Convertir todas las secuencias ‘%xx’ al valor del carácter cuyo valor ASCII sea

‘xx’ en hexadecimal. Por ejemplo convertir ‘%3d’ a ‘=’.

Esto se hace necesario porque la larga cadena original esta codificada según el código URL, para
permitir los signos ‘&’, ‘=’, y todo lo que el usuario introduzca. Pero, ¿de donde se obtiene la
cadena de entrada? Esto dependerá del método por el cual el formulario haya sido enviado:

Para los envíos con GET, será la variable de entorno QUERY_STRING.

Para los envíos con POST, habrá que leer del STDIN. El número exacto de bytes a leer estará en
la variable de entorno CONTENT_LENGTH.

DEVOLVIENDO LA RESPUESTA AL USUARIO

Primero, escribir la linea

Content-Type: text/html

más otra línea en blanco en el STDOUT. Después, escribiremos nuestra pagina de respuesta en
HTML al STDOUT, y será enviada al usuario cuando el script esté ejecutado.

Sí, estamos generando código en HTML en tiempo real. No es difícil, si no más bien directo. El
código HTML fue diseñado lo suficientemente simple para poder ser generado por este método.

174
GUARDANDO LA ENTRADA DEL USUARIO EN UN ARCHIVO

En este apartado vamos a guardar los datos escritos por el usuario en un archivo para poder
recuperarlos posteriormente. Como ejemplo utilizaremos un formulario para enviar chistes. Este
formulario obtendrá la siguiente información y lo guardará en las variables indicadas entre
paréntesis:

Nombre del Usuario (nombre)

Un Chiste (chiste)

Para ello creamos un formulario simple con el siguiente código:

<form method="POST" action="http://www.uva.es/cgi-bin/chiste-envio.pl">

<P>Tu nombre: <input name="nombre"></P>

<P>El chiste: <textarea cols=60 rows=5 name="chiste"></textarea></P>

<P><input type="submit" value="Enviar"><BR>

<input type="reset" value="Borrars"></P>

</form>

Nuestro programa colocará está información para que la podamos dar el visto bueno. El programa
devolverá una nota al usuario indicándole que su envío será revisado más tarde.

Por consistencia , llamaremos a este script chiste-envio.pl.

Necesitamos iniciar y comentar nuestro script. Utilizaremos la librería cgi-lib.pl de Steve Brenner’s
para facilitar la entrada de formularios..

Seguiremos con el script que coja la entrada y devuelva e siguiente mensaje:

Gracias _nombre_, tu envío será revisado en breve.

El script que realiza esto es el siguiente:

#!/usr/local/bin/perl

# chiste-envio.pl

# Este script añade el chiste al archivo de chistes.

# Devuelve una nota al usuario, indicando que su chiste será revisado.

push(@INC,"/p/www/httpd/cgi-bin/");

175
require("cgi-lib.pl");

&ReadParse;

print &PrintHeader;

print "<HTML><HEAD>\n";

print "<TITLE>Reconocimiento de chiste</TITLE>\n";

print "</HEAD><BODY>\n";

print "Gracias ",$in{'nombre'},",Tu envío será revisado lo antes posible.


.<P>\n ";

print "</BODY></HTML>\n";

Ahora al tema central, añadir a un archivo. Para hacerlo necesitamos un archivo con permiso de
escritura para el daemon http. La creación de este archivo variará entre distintos sistemas, y
necesitaras consultar a tu webmaster. En este caso usaremos el archivo:

/users/jperez/www/tutor/chiste.txt

Para abrir el fichero para añadir al final usaremos el comando de perl para abrir ficheros, que tiene
la siguiente sintaxis:

open(FILEHANDLE,">>nombrearchivo");

FILEHANDLE es como llamaremos al archivo mientras esté abierto. Es similar a una variable.
Nombrearchivo es el archivo a abrir. Los signos ‘mayor’ (>>) son importantes, y como en el shell
indican ‘añadir a un fichero’.

Así la orden de apertura quedará así:

open(CHISTE,">>/users/jperez/www/tutor/chiste.txt");

Nota: Es aconsejable usar letras mayúsculas para FILEHANDLE para ayudar a distinguirlo de las
variables.

Escribir a un fichero es idéntico a como hicimos previamente. La única diferencia es que el


FILEHANDLE es el primer argumento de la sentencia print, y está separado de lo que será
imprimido por un espacio. Por ejemplo para escribir la linea "Las rosas son rojas" al FILEHANDLE
CHISTE, escribiremos:

print CHISTE "Las rosas son rojas\n";

Escribir variables se realiza de la misma manera:

print CHISTE "Las rosas son ",$in{'colorrosas'},"\n";

El código para nuestro ejemplo necesitará escribir al archivo:

176
1. El nombre del usuario precedido con la cadena "Nombre:"

2. Una línea en blanco.

3. El chiste enviado.

4. Una línea con 50 guiones.

El código es el siguiente:

print CHISTE "Nombre: ",$in{'nombre'}," \n";

print CHISTE "\n";

print CHISTE $in{'chiste'},"\n";

print CHISTE "--------------------------------------------------\n";

Ahora solo nos queda cerrar el fichero, y esto lo hacemos con el comando:

close FILEHANDLE;

DEVOLVIENDO UNA PÁGINA QUE NO HEMOS GENERADO

En este apartado crearemos un libro de visitas sencillito. Durante el proceso de realización,


haremos bastantes cosas de forma ordenada.

Devolveremos una página html que nosotros no habremos creado en tiempo real. Esto se hace
principalmente para demostrar la directiva de localización.

Hay que verificar que todos los campos tienen una entrada, y que la direción de correo electrónico
tiene un símbolo arroba (@).

Editar un documento html con un script, insertando información en el medio.

Vamos a empezar creando un formulario que coja la siguiente información en las variables
indicadas entre paréntesis.

(nombre)

(email)

(comentarios)

Colocamos un comentario en HTML que contenga la cadena "INSERTAR AQUÍ" en el formulario


donde vayamos a insertar las nuevas entradas.

<!--INSERT HERE-->

Este formulario llamará al script, guestbook.pl. El formulario guestbook.html será el siguiente:

177
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

<html>

<head>

<title>Libro de visitas</title>

</head>

<body>

<h1>Firma el formulario</h1>

<P>Por favor, rellena todos los campos:</P>

<hr>

<form method=POST action="http://www.ctv.es/cgi-bin/guestbook.pl">

<P><input name="nombre"><BR>

Nombre</P>

<P><input name="email"><BR>

Dirección e-Mail [Debe tener una arroba @]</P>

<P><textarea rows=3 cols=70 name="commentarios"></textarea><BR>

Comentarios:</P>

<P><input type="submit" value="Añadir tus comentarios"><BR>

<input type="reset" value="Borrar formulario"></P>

</form>

<HR>

<!--INSERT HERE-->

<P>Última modificación 21/9/00

</body>

</html>

Como se puede ver, los nombres serán añadidos al final del formulario.

Estos son los pasos para realizar nuestra tarea:

178
1. Verificar la entrada, devolviendo un mensaje de error si hay un problema.

2. Uraremos un bloqueo de archivo denominado ‘del pobre’. Creando un nuevo archivo


denominado. Si este archivo existe el programa se detendrá durante un segundo y lo volverá a
intentar.

3. Abriremos y leeremos el archivo del libro de firmas actual: guestbook.html.

4. Borraremos este archivo, y escribiremos un nuevo fichero que consistirá en la antigua


información con toda la nueva en el sitio apropiado. Usaremos el comentario <!--INSERTAR
AQUÍ--> como marcador donde añadir entradas.

Nota: Puede ser deseable hacer una copia de seguridad del archivo, antes de borrarlo.

No lo hacemos en este ejemplo, pero lo recomiendo en cualquier desarrollo. Se podrá hacer por
cualquier método, incluido una llamada al sistema para copia r (cp).

5. Retornar una directiva de lugar apuntando a una página de agradecimiento que ya hayamos
preparado.

6. Desbloquear borrando el archivo .guestlock.

Obviamente, este no es el mejor libro de visitas, pero servirá como un buen ejemplo, y es
fácilmente ampliable.

Empecemos:

1. Como es habitual nuestro script deberá empezar con una llamada al Perl, los comentarios
apropiados, y una llamada a la rutina ReadParse. No lo detallaremos aquí, ya que se hizo
anteriormente.

2. Para empezar debemos verificar los datos de entrada. Nos queremos asegurar de que no hay
campos en blanco, y de que la dirección e-Mail contiene una arroba (@). Para ventaja nuestra, las
cadenas nos vienen dadas sin los espacios en blanco, justo igual que los navegadores cuando
presentan páginas html. Esto significa que solo debemos comprobar que ninguna de las cadenas
es igual a la cadena vacía, "". En perl, como en muchos lenguajes, las cadenas se comparan de
manera diferente a los números. Usaremos ‘eq’ para comprobar la igualdad de cadenas, y el signo
‘==’ para comprobar la igualdad de números. Usearemos ‘ne’ y ‘!=’ respectivamente para las
comparaciones ‘no igual’.

Podemos hacerlo de la siguiente manera:

if ($in{'nombre'} eq "") {

# Hay una cadena vacía, devolver mensaje de error

# salimos al final del script ahora, tenemos un error

exit;

179
Como podrás adivinar, Ahora no ponemos el código para devolver el mensaje de error, en el
ejemplo de arriba. Aún así muestra lo facil que es comprobar que un campo está vacío.

Nota: Los paréntesis () y las llaves ({}) son importantes. Los paréntesis contienen lo que se está
comprobando como verdadero o falso, y las llaves contienen las sentencias a ejecutar si es
verdadero.

Como vamos a realizar varias comprobaciones de cadenas vacías, y vamos a devolver el mismo
error para todas ellas, podemos incluirlas en la misma sentencia if-then uniéndolas por OR logicos
||, en perl. El OR significa que alguna de las comprobaciones tienen que ser verdad, para que toda
la sentencia sea cierta.

Un ejemplo de comprobar si tres variables no están vacias podría ser este:

if (($in{'nombre'} eq "") || ($in{'email'} eq "") || ($in{'comentarios'}


eq "")) {

# algun campo está en blanco, devolver mensaje de error

# salimos al final del script ahora, tenemos un error

exit;

De nuevo he omitido, el codigo del mensaje de error, ya que es sencillo construir un pequeña tabla
con los codigos para devolver un código de error útil para el usuario. El código que he elegido para
hacerlo aparece más tarde en el código final de guestbook.pl.

La última verificación que necesitamos realizar es comprobar que la dirección eMail del usuario
contiene un signo (@). Lo realizaremos fácilmente con las potentes expresiones regulares que el
perl proporciona.

Una expresion regular sencilla para chequear esto sería /\w*@\w*/. Simplemente describe una
situación donde una palabra aparece delante y detras de un símbolo @. Las expresiones regulares
son una herramienta extremadamente potente, pero no entran dentro del dominio de esta lección.

Para llevar a cabo la comprobación de que la expresión se cumple, simplemente comparamos.


Funcionará como las comparaciones normales, pero usando el símbolo ‘=~’ para igualdad y el
símbolo ‘!~’ para desigualdad. La expresión regular podría codificarse así:

if ($in{'email'} !~ /\w*@\w*/) {

# La expresión regular no es igual, devolver mensaje de error.

De nuevo, he omitido el mensaje de error para este código.

3. Ahora comprobaremos la existencia de nuestro archivo de bloqueo. Si existe, nos detendremos


por un segundo para un segundo intento. Si no existe deberemos crearlo, bloqueando de este

180
modo el archivo. Para hacerlo necesitaremos un bucle continuo sobre una sentencia if-then-else
que compruebe la existencia del archivo, y que terminará cuando hayamos añadido la entrada.

Para el bucle en perl usaremos la sentencia while. Esta sentencia ejecuta repetidamente lo que
está entre llaves hasta que la condición entre paréntesis es falsa. Un ejemplo para clarificarlo:

while (condición) {

# Codigo a ejecutar mientras la condición sea cierta

Las condiciones son del mismo tipo de las que pondríamos en una sentencia if-then. Vamos a usar
de hecho una sentencia if-then con la clausula else en este bucle. Como ya sabemos las
sentencias if-then-else ejecuta el then cuando la condición es cierta y el else cuando es falsa.

if (condición) {

# Código a ejecutar si la condición es CIERTA

else {

# Código a ejecutar si la condición es FALSA

Para comprobar la exiastencia de un archivo, usaremos el operador ‘-e’ del nombre del archivo. No
se debe olvidar que el archivo de bloqueo debe estar en un lugar donde el httpd pueda escribir. En
este caso lo colocaremos en el directorio users/jperez/www/tutor/.

Si el fichero existe, nos dentendremos durante un segundo, y lo volveremos a intentar. El lenguaje


perl tiene un comando de espera con la forma:

sleep(# segundos).

Aquí tenemos como debemos realizar el chequeo, con el comando de espera. Todo ello queda
incluido en un bucle while que comprueba que la variable quitar vale 1 antes de salir.

$quitar = 0;

while ($quitar != 1) {

if (-e "/users/jperez/www/tutor/.guestlock") {

# El archivo existe. Esperaremos un segundo

sleep(1);

181
else {

# El archivo no existe, haremos el trabajo para añadir la entrada.

# Aquí deberemos dar a $quitar valor 1.

Para crear el archivo de bloqueo, simplemente deberemos abrir y cerrar el archivo. Así crearemos
un archivo de 0 bytes de longitud, que servirá en nuestro chequeo, y bloqueará otros procesos que
la gente pueda realizar en ese momento, hasta que este haya acabado.

Para ello esaremos un trozo de código que aquí se detalla:

open(LOCK,">/users/jperez/www/tutor//.guestlock");

close LOCK;

4. Ahora tnemos un bloqueador del fichero. Ahora deberemos abrir y leer todos los contenisdos del
guestbook.html. Esto se hace fácilmente abriendo el archivo para lectura. En el comando open
antes empleado usaremos el símbolo (<) donde antes usamos (>>). El resultado será:

open(FILEHANDLE,"<nombrefichero");

El código será::

open(GB,"<users/jperez/www/tutor/guestbook.html");

Leer del fichero es igual de fácil. Perl perimite usar el FILEHANDLE entre los símbolos (<>) para
sustituir a la próxima línea del fichero.

Así pues, podemos poner algo como esto:

$linea = <GB>;

Así leeremos una línea del fichero apuntado por GB, y avanzará el puntero a la siguiente línea
automáticamente. Esto significa que la siguiente sentencia como esta leerá la siguiente línea.
Podremos leer el archivo entero en un bucle, saliendo solo cuando no quede nada más,. Pero hay
un modo más fácil, podemos usar un vector. Un vector es una variable, con mucha información que
puede ser accedida individualmente. Ya hemos usado arrays asociativos en la construcción
$in{'variable'}. Recuerda que se tiene el elemento etiquetado como variable en el vector asociativo
$in. Usaremos un vector ordenado numericamente. Esto significa que la información es
almacenada en el vector en el orden en la que la ponemos, y podemos referenciar el elemento n-
ésimo elemento añadido, donde n es un número cualquiera. Estos vectores son referenciados con
el signo @, y se usan de manera similar a los vectores asociativos cuando queremos recuperar un
solo elemento de él. El siguiente ejemplo lo explica:

@pepe # Este es el vector pepe entero, con todos sus elementos

182
$pepe[4] # El el quinto elemento del vector pepe. Notar que

# se empieza a contar desde 0, y que por tanto:

$pepe[0] # es el primer elemento del vector. (Igual que en el lenguaje C)

Perl proporciona un modo rápido para llenar un vector con el contenido de un archivo. Podemos
usar la sentencia @vector = <FILEHANDLE>. Se leerá cada linea del fichero apuntado por
FILEHANDLE, y seran colocados secuencialmente en el vector. Para leer el libro de visitas entero,
deberemos usar:

@lineas = <GB>;

No debemos olvidarnos de cerrar el fichero:

close GB;

5. Vaciar el archivo es muy sencillo. Simplemente debemos reabrirlo para escritura sin añadir. Esto
significa usar un ‘>’ en vez de dos. Una vez hecho esto debemos imprimir cada línea del fichero,
sustituyendo lo que el usuario escribió justo delante del marcador.

Para llevar a cabo la sustitución usaremos la función s/oldpattern/newpattern/, que reemplaza el


patrón antiguo con el nuevo. La buena noticia es que modemos usar metacaracteres como \n para
reemplazar varias líneas. Para que esto afecte a una variable que contiene una cadena usaremos
un operador. La sentencia quedará así:

$linea =~ s/oldpattern/newpattern/

Realmente haremos una sustitución en los comentarios, para convertir las nuevas líneas en
comandos <BR>, de manera que las líneas queden tal y como el visitante las escribió. Para hacerlo
pondremos:

$in{'comentarios'} =~ s/\n/<BR>\n/go;

La g que va detrás del patrón significa que se hará esto para cada línea en la variable, la o significa
compilar esta expresión regular de ma nea que concuerde más rápido. Es bueno hacerlo.

Para realizar la sustitución y añadir los comentarios del usuario para cada línea del vector,
usaremos uin bucle foreach. Esto significa para cada elemento de la lista, coloca el elemento en la
variable_de_bucle, y ejecuta las sentencias que están entre las llaves ({}). Esto sería:

foreach $variable_de_bucle (lista) {

#cosas a hacer

Queremos insertar el nombre de la persona con su dirección e-Mail entre paréntesis, seguido de
sus comentarios. Esto lo incluiremos en un parrafo HTML, seguido de un comando <HR>. No
tenemos que olvidarnos de incluir un nuevo marcador <!--INSERTAR AQUÍ>. Lo pondremos
primero así las nuevas entradas serán añadidas al principio de la página. Mi codigo será:

183
open(GB,">/users/jperez/www/tutor/guestbook.html");

foreach $linea (@lineas) {

$linea=~ s/<!--INSERTAR AQUÍ-->/<!--INSERTAR AQUÍ-->\n<P>Nombre:

$in{'nombre'}
($in{'email'})<BR>\nComentarios:<BR>\n$in{'comentarios'}<\/P>\n<HR>\n/o;

print GB $linea;

close GB;

6. Ahora que hemos reescrito el archivo, debemos desbloquearlo, borrando el archivo .guestlock .
Es sencillo, ya que perl tiene un buncion borrar:

unlink(lista of ficheros);

Así tendremos que poner:

unlink("/users/jperez/www/tutor/.guestlock");

7. El ultimo paso es apuntar a mi página de agradecimiento. Y poner la variable $quitar = 1; . HTTP


nos permite hacer esto fácilmente con la directiva de localización.

Simplemente devolvemos la línea:

Location: url

Instead of:

Content-Type: text/html

Esto lo resolvemos con la siguiente sentencia print :

print "Location:
http://www.ctv.es/users/jperez/www/tutor/agradecimiento.html\n\n";

La nueva segunda línea es significativa. Los códigos de retorno Mime, de los cuales la localización
es uno de ellos, requiere dos nuevas lineas siguiéndolo para trazar el fin del código de retorno.
Olvidar la nueva segunda línea provocará un daño irrecuperable.

Poner la variable ‘quitar’ a 1 es trivial:

$quitar = 1;

El código final para el archivo guestbook.pl será:

184
#!/usr/local/bin/perl

# guestbook.pl

# Procesa las entradas a un libro de firmas

#Usaremos la librería cgi-lib.pl para manejar la entrada

push(@INC,"/p/www/httpd/cgi-bin");

require("cgi-lib.pl");

&ReadParse;

if (($in{'nombre'} eq "") || ($in{'email'} eq "") || ($in{'comentarios'}


eq "")) {

# algún campo en blanco, devolver mensaje de error

print &PrintHeader;

print "<HTML>\n";

print "<HEAD>\n";

print "<TITLE>Mensaje de error</TITLE>\n";

print "</HEAD>\n";

print "<BODY>\n";

print "\n";

print "<H1>Ha ocurrido un error</H1>\n";

print "\n";

print "<P>No has completado todos los campos Por favor vuelve a
intentarlo.</P>\n";

print "</BODY>\n";

print "</HTML>\n";

# llamda para salir del script. Tenemos un error

exit;

185
}

if ($in{'email'} !~ /\w*@\w*/) {

# No es igual a la expresión regular. Enviar mensaje de error

print &PrintHeader;

print "<HTML>\n";

print "<HEAD>\n";

print "<TITLE>Mensaje de error</TITLE>\n";

print "</HEAD>\n";

print "<BODY>\n";

print "\n";

print "<H1>Ha ocurrido un error</H1>\n";

print "\n";

print "<P>Tu dirección email no contiene una @.</P>\n";

print "</BODY>\n";

print "</HTML>\n";

# llamada para salir ahora del script, tenemos un error

exit;

$quitar = 0;

while ($quitar != 1) {

if (-e "/users/jperez/www/tutor/.guestlock") {

# El fichero existe, esperamos un momento

sleep(1);

else {

186
# Creamos el fichero de bloqueo, de manera que el libro de firmas queda
bloqueado.

open(LOCK,">/users/jperez/www/tutor/.guestlock");

close LOCK;

# Abrimos y leemos el antiguo libo de firmas

# Nota: Crear una copia de seguridad no sería una mala idea ...

open(GB,"</users/jperez/www/tutor/guestbook.html");

@lineas = <GB>;

close GB;

# Preparamos los comentarios para html

$in{'comentarios'} =~ s/\n/<BR>\n/go;

# Vaciamos el libro de firmas antiguo, y lo volvemos a imprimir,


añadiendo la nueva entrada

open(GB,">/users/jperez/www/tutor/guestbook.html");

foreach $linea (@lineas) {

$linea =~ s/<!--INSERTAR AQUÍ-->/<!--INSERTAR AQUÍ-->\n<P>Nombre:

$in{'nombre'}
($in{'email'})<BR>\nComentarios:<BR>\n$in{'comentarios'}<\/P>\n<HR>\n/o;

print GB $linea;

close GB;

# desbloquear el archivo

unlink("/users/jperez/www/tutor/.guestlock");

# Devolver el nuevo libro de firmas, y poner $quitar = 1

print "Location:
http://www.ctv.es/users/jperez/www/tutor/thanks.html\n\n";

$quitar = 1;

187
}

Nota sobre el bloqueo de archivos:

El mecanismo de bloqueo de archivos usado arriba, no es perfecto ya que requiere varios pasos
para bloquear un archivo. Por ello es posible obtener un bloqueo o desbloqueo falso, aunque es
altamanete improbable. Una implementación mejot usara el sistema de ficheros nativo bloqueando,
vinculando, o algún otro método atómico. Desconozco si perl simula el bloqueo en sistemas que no
implementan el bloqueo de forma nativa.

Un método usando vínculos sin comentar sería:

$quit = 0;

while ($quit != 1) {

/users/jperez/www/tutor/guestbook.html

if
(link(/users/jperez/www/tutor/guestbook.html,/users/jperez/www/tutor/.gue
stlock)) {

# Archivo bloqueado, nos detenemos un momento

sleep(1);

else {

# Tenemos un bloqueo, hacemos lo que tengamos que hacer

unlink("/users/jperez/www/tutor/.guestlock");

SCRIPTS CGI QUE ENVÍAN CORREO

En este apartado crearemos un script CGI que envíe correo, y devolvera una página que indique
que el correo ha sido enviado. Sin embargo, los conceptos serán bastante geneales para permitir
que el script pueda ser adaptado a cualquier proyecto donde sea necesario enviár un correo desde
un script.

También veremos brevemente como examinar las areas de texto línea por línea.

Como siempre, cuando empezamos, necesitaremos un formulario.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

<html>

188
<head>

<link rev=made href="mailto:jperez@ctv.es">

<title>Enviar correo desde un script CGI</title>

</head>

<body>

<P>Este formulario encía correo a la dirección de la persona


mostrada.</P>

<form method="POST" action="http://www.ctv.es/USERS/cgi -bin/mail.pl">

<P>Tu dirección: <INPUT NAME="De" SIZE=36></P>

<P>Tu URL: <INPUT NAME="xurl" SIZE=36></P>

<P>Subject: <INPUT NAME="subject" SIZE=40></P>

<P>Mensaje:</P>

<P><TEXTAREA name="body" rows=10 cols=60></TEXTAREA></P>

<P><input type="submit" value="Enviar mansaje">

<input type="reset" value="Borrar todo"></P>

</FORM>

</P>

</body>

</html>

Ahora pasaremos al script. Como siempre deberá empezar con una llamada al perl, algunos
comentarios y una llamada a la rutina ReadParse, en la librería cgi-lib.pl. También haremos
verificaciones de que el cuerpo del mensaje no está vacío, y de que la dirección contiene una
arroba (@). Ya sabemos hacerlo, por que ya lo realizamos en el anterior apartado. Otra validación
será para comprobar que de pasan argumentos, lo pondremos porque la gente tiene tendencia a
llamar a los scripts de correo sin argumentos (eg: no desde un formulario), no entiendo por qué.

Para comprobar que no hay argumentos, simplemente examinaremos si el vector %in que la
librería cgi-lib.pl nos devuelve tiene alguna tecla. Recuerda, que ningún argumento, significa que
no nos han pasado nada, sin embargo, alguien puede pasar los argumentos en blanco, de aquí las
dos comprobaciones. La manera de comprobar los valores de las teclas del vector es usar la
función keys(). Esta función espera un array asociativo como argumento. Simplemante
comprobaremos que devuelve algo, imprimiendo un mensaje de error si no hay teclas. El código
pude ser este:

189
if (!keys(%in)) {

# niguna tecla ha sido pasada, imprimir mensaje de error, y si es


apropiado salir.

El signo ‘!’ al principio de la llamada a keys(), significa ‘no’ o negación.

Quiere decir que si keys() no devuelve nada (falso), sera negado para que sea cierto y el if se
ejecute.

Ahora que hemos validado las entradas, y se pueden realizar más comprobaciones, necesitaremos
enviar la carta. Para ello necesitaremos un programa que acepte una carta del stdin. Luego
usaremos sendmail en el ejemplo. Si no estás en un entorno Unix, necesitarás otro programa
apropiado para hacerlo. Como no conozco otro tipo de sistemas, no puedo hacer ninguna
recomendación.

Usar este programa será similar a escribir en un fichero. Necesitamos abrir el programa para
aceptar la entrada, escribir al FILEHANDLE. Abrir un programa que espera entradas por el stdin es
bastante fácil em Perl. Además, es muy fácil pasar el argumento de la línea de comandos. En este
ejemplo, abriremos sendmail, y diremos que busque en la carta la dirección de destino.

open(MAIL,"|/usr/lib/sendmail -t")

Como se puede observar, es igual que una llamada a fichero, pero los símbolos ‘>’ o ‘<’ han sido
sustituidos por un ‘|’ (tubería). Esto indica que lo que hay detrás de la tubería es un ejecutable, y
que lo que imprimamos en este FILEHANDLE se deberá pasar como entrada a el programa
ejecutable.

Nota: No he comprobado si la operación anterior terminó con éxito, pero deberíamos hacerlo. La
manera más sencilla de hacerlo, es apoyarnos en que el comando open devuelve true cuando ha
tenido éxito. Solo debemos hacer un OR entre el comando open y otro comando conociendo que
ese comando será ejecutado si el open falla. El ejemplo de abajo realiza un OR con el comando
die. Este comando imprime un mensaje de error y sale del programa.

open(MAIL,"|/usr/lib/sendmail -t") || die "La llamada a sendmail ha


fallado";

El imprimir la carta funciona como experamos. Recuerda, sin embargo, que estamos imprimiendo
un trozo de e-Mail, por lo que deberemos poner las cabeceras adecuadas, un línea en blanco y el
cuerpo del mensage. Puedes echar un vistazo a un e-Mail que hayas recibido y comprobar las
cabeceras. Decribiré abajo lo más importante. Los comentarios serán de ayuda.

# Esta es la línea ‘para’. Si tenemos el nombre y la dirección,


escribiremos

# primero el nombre y lurgo la dirección entre <>

print MAIL "To: $in{'De'}\n";

# Esta es la linea ‘De’. Pondremos el mismo nombre en la línea ‘De’ y en


la ‘para’

190
# Recuerda que no hay seguridad comprobando el email, por ello estas
líneas

# pueden ser falsificadas. NO FALSIFIQUES EL EMAIL, no es divertido y en


algunos lugares

# es un delito.

print MAIL "From: $in{De}\n";

# Esta es la linea ‘contestar a’. Esta línea se incluye debido a que


algunos programas

# son bastante tonotos y no siempre responden a la línea ‘De’.

# Al menos respetarán esta línea.

print MAIL "Reply-To: $in{De}\n";

# Lo siguiente son cabeceras X. Son creadas por el usuario y pueden


contener

# todo lo que desees. Incluyo una linea de descripción

# tambien he escrito las líneas REMOTE_HOST, REMOTE_ADDR, y REMOTE_USER


para

# ayudar al seguimiento (traking) de la carta.

# Solo escribo la línea X-URL si el usuario ha dado una url. Este tipo

# de comprobación probablemente hecha también en el X-Remote-Host y X-


Remote-User

print MAIL "X-mailer: Mail.pl, a cgi-bin script at


http://www.ctv.es/users/jperez/www/tutor/ /index.html\n";

print MAIL "X-Remote-Host: $ENV{'REMOTE_HOST'} ($ENV{'REMOTE_ADDR'})\n";

print MAIL "X-Remote-User: $ENV{'REMOTE_USER'}\n";

print MAIL "X-disclaimer: La línea De: puede estar falsificada ";

print MAIL "No confiar en un 100% sobre la integridad de este mail. ";

print MAIL "No somos responsables de este correo de ninguna manera\n";

if ($in{xurl} ne "") {

print MAIL "X-URL: $in{xurl}\n";

191
# Finalmente escribimosly we print the famous subject line. I have
appended a string.

# identifying this as WWW generated email, this is far from a


requirement.

# Notice the second new line. This is the blank line that will separate
the

# headers from the body. All mail must have this line.

print MAIL "Subject: $in{subject} (WWW generated email)\n\n";

# Now we are going to print the body. Because it was input into a
TEXTAREA

# field, it has new lines after each line. We can just print it like any
other

# field, knowing that the new lines will expand it properly.

print MAIL $in{'body'};

Solo quedan dos cosas. Primero debemos cerrar la conexión con sendmail. Segundo debemos
imprimir una página enseñando al usuario la carta que envía. Para cerrar la conexión, usaremos el
comando close, justo como en cualquier otro manejador:

close(MAIL);

Imprimir la respuesta no es diferente a las otras páginas generadas dinámicamente que ya hemos
creado anteriormente. Deberemnos dividir el campo TEXTAREA en líneas colocando un <BR> al
final de cada una. Esto se hace principalmente para demostrar como se divide un campo de texto.
Recuerda sin embargo que html no respeta las nuevas líneas. Con ello se consigue el poder hacer
los parrafos de manera más clara, pero el beneficio de hacerlo es cuestionable.

El valor del campo body (cuerpo del mensaje), no es más que un conjunto de frases separadas con
un retorno de carro. Podemos usar la función split() para separarlas. Esta función necesita dos
parámetros: la cadena o carácter para separar y la variable a separar, y retorna un array con los
elementos separados. Usaremos split en un bucle foreach:

foreach $l (split('\n',$in{'body'})) {

print "$l<BR>\n";

Como se puede ver separa la variable $in{'body'} en partes cada nueva línea, y la imprime seguida
de un <BR>.

ESCRIBIENDO SCRIPTS CGI SEGUROS

192
Siempre que un programa interactúa con un cliente por red, existe la posibilidad de que el cliente
atcque al programa para conseguir un acceso. El script más inocente puede ser muy peligroso para
la integridad de tu sistema.

Teniendo eso en cuenta, me gustaría comentar unos pequeños consejos para conseguir que tu
programa no sea atacado.

Cuidado con la sentencia eval

Lenguajes como el Perl y el Bourne shell tienen un comando eval que permiten construir una
cadena y dejar al intérprete que la ejecute.

Esto puede resultar peligroso. Observa la siguiente sentencia en Bourne shell:

eval `echo $QUERY_STRING | awk 'BEGIN{RS="&"} {printf "QS_%s\n",$1}' `

Esta sentencia coge la cadena de entrada y la convierte en un conjunto de comandos de


declaración de variables. Desafortunadamente este script puede ser atacado mandando una
cadena de entrada que empiece por ‘;’.

No confíes en que el cliente haga algo

Un cliente correcto evitará todos los caracteres que tienen un significado especial para el Bourne
Shell en una cadena de entrada, y que hega que tu script malinterprete los caracteres. Un cliente
malintencionado usará esos caracteres para confundir a tu script y ganar acceso desautorizado.

Cuidado con popen() y system()

Si usas datos del cliente para construir una llamada a popen() o system(), aseguraté de
poner un backslash delante de cada carácter que tenga un significado especial para el
Bourne Shell antes de llamar a la función. Lo podrás hacer con una sencilla función en C.
Si quieres más información sobre la seguridad en el WWW, consulta WWW Security FAQ
en http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html.

193

You might also like