Escolar Documentos
Profissional Documentos
Cultura Documentos
1 de 99
Jeisson Hidalgo-Cspedes
Versin 0.2.8. 2011-Dic-13
Tabla de contenidos
22/09/2015 11:52 a. m.
2 de 99
Encabezados de secciones
Prrafos
Texto estructurado
Listas
3.3 Enlaces
3.3.1 Anclas
3.3.2 Ventana objetivo
3.3.3 Acceso con el teclado
3.4 Imgenes
3.4.1 Tamaos de imagen
3.4.2 Formatos de imgenes
3.4.3 Icono de favoritos
3.5 Tablas
3.6 Formularios
3.7 Objetos multimedia
3.8 Elementos genricos
4 Hojas de estilo en cascada CSS
4.1 Generalidades de las hojas de estilo
4.1.1 Ubicacin de las reglas de estilo
4.1.2 El principio de cascada
4.1.3 El operador @
4.2 Selectores
4.3 Valores de propiedades
4.4 Propiedades
4.4.1
4.4.2
4.4.3
4.4.4
El
El
El
El
modelo
modelo
modelo
modelo
de
de
de
de
fuente
color
caja
visualizacin
Cdigo
Cdigo
Cdigo
Cdigo
JavaScript
JavaScript
JavaScript
JavaScript
en
en
en
en
el elemento script
un archivo externo
los eventos intrnsecos
el pseudoprotocolo javascript:
Nmeros
Cadenas de caracteres (strings)
Conversiones entre nmeros y strings
Booleanos
Funciones
Objetos
Arreglos
Valores especiales
Objetos especiales
22/09/2015 11:52 a. m.
3 de 99
5.3 Expresiones
5.3.1 Operadores
5.3.2 Sentencias
5.5 Pseudoclases
5.6 Programacin del navegador
5.6.1 El ambiente de desarrollo del navegador
5.6.1.1 El modelo de ejecucin de JavaScript
5.6.1.2 Consideraciones de seguridad
5.6.2 El objeto window
5.6.2.1 Temporizadores y animaciones
5.6.2.2 Informacin del navegador, la ventana y la pantalla
5.6.2.3 Abrir y manipular ventanas
5.6.2.4 Ubicacin del documento
5.6.2.5 Cuadros de dilogo
5.6.3 El objeto document
5.6.3.1 El modelo de objetos del documento (DOM)
5.6.3.2 Localizar elementos en el documento
5.6.3.3 Manejo de eventos
6 El servidor web
6.1 Instalacin y ejecucin del servidor web
6.2 Configuracin del servidor web
6.2.1 La directiva include
6.2.2 El mdulo HTTP Core
6.2.2.1 Servidores virtuales
6.2.2.2 El bloque location
6.2.2.3 MIME types
6.2.3 Server Side Includes module
6.2.4 CGI y FastCGI
6.2.5 PHP a travs de FastCGI
El mtodo GET
El mtodo POST
Seguridad y validacin de datos
Controles en el formulario
Validacin de datos con JavaScript
8 Bibliografa
22/09/2015 11:52 a. m.
4 de 99
1.1 Historia
La web fue conceptualizada en un artculo de 1989 de Tim Berners-Lee, quien se convertira en uno de sus grandes lderes.
A finales de 1990, Berners-Lee desarroll el Protocolo de transferencia de hipertexto (HTTP, HyperText Transfer Protocol), el
primer servidor web llamado CERN-httpd; el primer navegador llamado WorldWideWeb, que tambin era un editor web; el
lenguaje de marcado de hipertexto (HTML, HyperText Markup Language); y las primeras pginas web que hablaban sobre el
proyecto mismo.
La aparicin pblica de la web fue en 1991, cuando Berners-Lee describi el proyecto en un grupo de noticias (Usenet
newsgroup). Haba nacido un mecanismo eficiente que permite a cualquiera ser autor, compartir material de inters al
mundo, y hacer referencia al existente a travs de hiper-enlaces.
La difusin de la web fue lenta. Inicialmente fue adoptada por universidades y grupos cientficos. Los documentos web eran
muy sencillos y la mayora de navegadores corran en modo texto, unos pocos eran grficos como el escrito por Berners-Lee
en una NeXT. Desde 1992 muchos navegadores se construyeron, pero el ms influyente de todos fue Mosaic.
En 1993 el National Center for Supercomputing Applications (NCSA) de la University of Illinois en Urbana-Champaign
(UIUC), introdujo el navegador grfico Mosaic, como un proyecto de investigacin. NCSA licitaba su cdigo fuente a otras
compaas para que crearan sus propios navegadores, incluso comerciales. Tras de graduarse, el lder del proyecto Mosaic,
Marc Andreessen, fundara la compaa Netscape en 1994, para comercializar su navegador Netscape Navigator, el cual
corra transparentemente entre diversos sistemas operativos. Era gratis para uso no comercial, por lo que se convirti en el
navegador ms usado del mundo.
En 1994 Berners-Lee funda el World Wide Web Consortium (W3C) en el Instituto Tecnolgico de Massachusetts (MIT,
Massachusetts Institute of Technology), apoyado por varias instituciones y empresas con el fin de crear estndares y
recomendaciones para mejorar la calidad de la web.
22/09/2015 11:52 a. m.
5 de 99
HTML distintos que provocaron que los autores de millones de pginas tuvieran que escoger por uno o el otro. Era comn
ver imgenes indicando que el sitio se vea mejor con un navegador particular, incluso hasta de una versin especfica.
Mientras tanto el proceso de estandarizacin avanzaba lentamente. En junio de 1993 el Consorcio Web (W3C) propone
varios borradores de estandarizacin y en noviembre de 1995, la Internet Engineering Task Force (IETF) aprueba el HTML
2.0 que luego se convertira en estndar internacional en 1997. El W3C propone HTML 3.0 en abril de 1995 pero la IETF no
realiza ninguna accin. Los navegadores tomarn luego ideas de estas iniciativas en proceso y las implementarn a su
manera para atraer usuarios.
A inicios de 1997 la IETF traslada la responsabilidad de estandarizacin al W3C, quien publicara recomendaciones con una
eficiencia mayor. Se publica el HTML 3.2 adoptando etiquetas y atributos de marcado visual de Netscape (como <b> y
<font>). A final del mismo ao, el W3C presenta el trabajo de estandarizacin ms notorio hasta la fecha, conocido como
HTML 4.0. Un esfuerzo que considera las extensiones derivadas de la guerra de navegadores y las races del HTML. En ella,
las etiquetas de marcado visual seran desaprobadas ("deprecated") en favor de CSS; pero su uso se haba difundido tanto
que el W3C decidi generar tres variaciones del HTML 4.0:
HTML 4.0 Strict. Prohbe elementos "deprecated".
HTML 4.0 Transitional. Permite elementos "deprecated".
HTML 4.0 Frameset. Permite construir pginas basadas en "frames", con los elementos <frameset> y <frame>.
Dos aos despus, a finales de 1999, se le hara una ligera modificacin al estndar HTML 4.01, cuya variacin estricta
(HTML 4.01 Strict) sera adoptado como estndar internacional (ISO/EIC 15445:2000), suplantando la versin 2.0 de 1997.
Tras ello, el trabajo de estandarizacin dejara de lado al HTML para concentrarse en el XHTML.
En febrero de 1998 el W3C public el estndar XML (Extensible Markup Language). En enero de 2000 se reformul HTML
4.01 como una aplicacin XML en lo que conoce como XHTML 1.0. Una actualizacin XHTML 1.1 se emiti como
recomendacin en mayo de 2001 que permite modularizar el HTML para necesidades especficas, las ms sobresalientes han
sido XHTML-Basic que incluye el conjunto mnimo de caractersticas que cualquier navegador debe soportar, incluso de
dispositivos mviles y XHTML-MP (mobile profile) con controles aptos para dispositivos mviles.
Entre agosto de 2002 y julio de 2006, el W3C trabaj en XHTML 2.0 que slo alcanz el nivel de notas y no de
recomendacin. En el 2008 el W3C considerara como base del futuro (X)HTML[1] 5.0, un borrador llamado (X)HTML5
desarrollado por un grupo de interesados, compuesto principalmente por fabricantes de navegadores alternativos (Mozilla
Foundation, Opera Software y Apple), ajenos al W3C, que se autodenominaron WHATWG (Web Hypertext Application
Technology Working Group). A diferencia de XHTML 2.0, (X)HTML5 estara ms centrado en el desarrollo de aplicaciones
web y no en la especificacin de documentos.
22/09/2015 11:52 a. m.
6 de 99
Aunque no es un estndar an, la segunda guerra ha llevado a la mayora de navegadores a implementar (X)HTML 5.0 o al
menos las secciones ms estables de sus borradores.
1.1.4 Notas
[1]
En este documento se usarn los trminos HTML y XHTML para referirse a cada notacin por separado, o (X)HTML
cuando algo aplique a ambas por igual.
[2]
De acuerdo a la estadsticas del W3C en http://www.w3schools.com/browsers/browsers_stats.asp
Navegador
Cliente 1
Archivos
HTML
Servidor
web
HTTP
Servidor
Navegador
Cliente 2
Figura 1.1. Arquitectura web simple
El autor que quiera publicar un sitio web, construye un conjunto de pginas web en notacin (X)HTML junto con imgenes,
estilos y otros medios, y las almacena en una computadora que est siempre conectada a Internet, a la cual se le llama el
servidor. Un programa especial, llamado servidor web, el cual tiene acceso de lectura a dichas pginas, estar siempre en
esta computadora escuchando por un puerto TCP (Transmission Control Protocol), normalmente el 80 u 8080.
Un lector que quiera visitar el sitio debe conocer la direccin del servidor, es decir su nmero IP, ya sea introducindolo
directamente o a travs del servicio de nombres de dominio (DNS, Domain Name Service) y el puerto donde el servidor web
est escuchando. El lector carga un programa especial en su computadora llamado navegador web (web browser) e
ingresa en l la direccin del servidor y el puerto, la cual respeta una notacin estndar conocida como localizador uniforme
de recursos (URL). El navegador intentar establecer una conexin TCP con el servidor al puerto indicado o al 80 si se
omite. El servidor web aceptar la conexin. A partir de este momento el cliente y el servidor pueden comunicarse
libremente, pero para que ambos puedan entenderse se necesita un idioma comn: el protocolo de transferencia de
hipertexto (HTTP, HyperText Transfer Protocol).
El protocolo HTTP establece que el cliente, tambin conocido como user agent, siempre hace solicitudes de recursos para
mostrarlos al usuario, y el servidor responde a ellas, no el recproco. Las solicitudes del cliente y las respuestas del servidor
estn codificadas como se ver luego.
En lo que resta de esta seccin se explicarn los conceptos que componen la arquitectura web con ms detalle y en la
siguiente seccin, el proceso tpico en que un autor construye su sitio web y lo hace pblico para que los visitantes
interaccionen con l.
22/09/2015 11:52 a. m.
7 de 99
Cualquiera puede implementar un servidor web escribiendo un programa que espere conexiones en algn puerto TCP y
hable por l HTTP. Sin embargo, para la mayora de situaciones, es apremiante utilizar un servidor web existente. La Tabla
1.1 lista los ms populares en la actualidad.
Nombre
Fabricante
Licencia
Detalles
Apache HTTP
Server
Apache
Libre (Apache
License)
Internet
Information
Services (IIS)
Microsoft
Propietario /
Comercial
nginx
Igor
Sysoev
Libre (BSD)
Naci como una alternativa de Apache caracterizada por el alto rendimiento y bajo
consumo de recursos. Corre en la mayora de sistemas operativos. Sirve
aproximadamente 8% de las pginas web del mundo.
Uso interno
lighttpd
lighttpd
Libre (BSD)
Fabricante
Licencia
Libre (L/GPL)
Navegadores
Gecko
Mozilla Project
Firefox
WebKit
Trident
Microsoft
Propietario
Internet Explorer
Presto
Opera Software
Propietario
Opera
http://www.amazon.com/
http://www.w3.org/TR/html401/struct/tables.html#edef-CAPTION
http://acme.co.cr:8080/index.php
https://24.168.39.221/cgi-bin/book?id=4596098&action=remove
ftp://msoto:w33n8rf1@down.antivirus.net/current/setup.exe
22/09/2015 11:52 a. m.
8 de 99
que DNS no es sensitivo a maysculas ni minsculas, da lo mismo acceder a DRUPAL.org, por ejemplo.
3. Puerto. Indica el puerto que ser usado en la conexin TCP. Por ejemplo, http://myserver.com:10000/ har que el
navegador establezca una conexin HTTP en el puerto 10000, probablemente para administracin del servidor. Si se
omite el puerto en el URL se asumir el por defecto para el esquema usado. Por ejemplo, para http es 80, para https
es 443 y para ftp es 21. Una lista de protocolos y sus puertos por defectos puede a conveniencia consultarse en la
Wikipedia.
4. Ruta. Contiene la ruta para encontrar el recurso. Puede ser relativa al sistema de archivos del servidor o un "alias"
que ayude a especificar el recurso, por ejemplo, http://mibibl.net/revistas/acm.png. Es muy probable que sea
sensitiva a maysculas si el sistema de archivos del servidor lo es tambin.
5. Parmetros. Si el recurso es generado por una aplicacin en el servidor web, a esta se le pueden enviar parmetros
en forma de parejas parametro=valor y separadas por ampersands (&) si son varias parejas, por ejemplo,
https://mibibl.net/revista.php?id=23091&action=devolucion&user=chema. A esta lista de parmetros se le suele
llamar "query string".
6. Identificador de fragmento. Es un nombre que sirve para identificar una parte (fragmento) o un punto particular de
un documento web. Cuando se especifica un identificador de fragmento en un URL, provoca que el navegador cargue
el documento y automticamente se desplace ("scroll") hasta el fragmento en cuestin. Por ejemplo,
http://misitio.co.cr/docs/tesis.html#Cap03.
7. Usuario y contrasea. Si para acceder al recurso se necesita que el visitante se autentique, algunos protocolos
permiten indicar las credenciales en el URL mismo. Es poco comn y una prctica no recomendada incluir contraseas,
ya que el URL normalmente es pblico y carece de seguridad. Ejemplo, ftp://mmortadela@sjmuni.go.cr/vaca/mu.pdf.
Request line
Status line
empty line
empty line
Message body
Message body
La Figura 1.3 muestra dos ejemplos de mensajes HTTP. Los cambios de lnea son importantes por lo que se muestran en
rojo. En las siguientes secciones se explica cada uno de los campos que conforman los mensajes HTTP.
HTTP/1.1 200 OK
Host: www.ejemplo.com
User-Agent: Chrome/13 (Linux)
<html><head>
<title>Carta al estudiante</title></head>
<body>...</body></html>
22/09/2015 11:52 a. m.
9 de 99
Los navegadores slo muestran el contenido del cuerpo de los mensajes al usuario, ocultando los dos primeros campos de
los mensajes usados en la negociacin con el servidor web. La extensin HTTP Headers para el navegador Chrome, y Live
HTTP Headers para Firefox, permiten al usuario visualizar y estudiar los campos ocultos de los mensajes que se
intercambiaron entre el cliente y el servidor durante la carga de una pgina.
1.2.4.2 Request line
En la primera lnea del mensaje de solicitud HTTP, llamada Request line, el cliente web indica al servidor el recurso de
inters (un URL) y la accin que desea el servidor tome con dicho recurso. La sintaxis del Request line es:
METHOD URL HTTP_version
El protocolo HTTP define 9 acciones que un cliente web puede solicitar al servidor, reciben el nombre de Request methods
y se listan en la Tabla 1.3. El protocolo HTTP indica que todo servidor web debe almenos implementar GET y HEAD, e
idealmente OPTIONS.
Mtodo
Descripcin
GET
Solicita una copia completa del recurso cuya identificacin esta dada por el URL que le sigue. A travs de directivas en el
encabezado (el campo que sigue en el mensaje) se pueden hacer solicitudes condicionales (Conditional GET), por ejemplo,
obtener una copia del recurso slo si ha cambiado a partir de una fecha, o una solicitud parcial (Partial GET), por ejemplo,
obtener slo un segmento del recurso. Estos detalles se explican en el RFC-2616.
HEAD
Es idntico al mtodo GET excepto en que el servidor web no debe retornar un Message body en el mensaje de respuesta
HTTP. Esto permite al cliente obtener metadatos de un recurso, como para saber si ha cambiado en el servidor u otros fines.
OPTIONS
Retorna los mtodos HTTP que el servidor soporta para un recurso dado (con un URL) o en general por el servidor web
mismo (con un ' *' en lugar de un URL).
POST
Enva datos, normalmente ingresados en un formulario web, en el campo Message body del mensaje de solicitud HTTP, al
recurso identificado por el URL, normalmente un programa en el servidor que procesar o almacenar dichos datos.
PUT
"Sube" (upload) un recurso identificiado por el URL cuyo contenido es enviado en el Message body al servidor, el cual
reemplaza el recurso anterior si existe. Se diferencia de POST en la semntica del URL. En POST el URL especifica una
aplicacin que recibe los datos y los procesa; mientras que en PUT el URL es la identificacin del recurso mismo.
PATCH
DELETE
Solicita al servidor eliminar el recurso identificado por el URL. Normalmente est deshabilitado por defecto en la mayora de
servidores web.
TRACE
Permite rastrear servidores intermedios que procesan la solicitud HTTP. Esto es til para estudiar el comportamiento de
servidores proxy en especial si implementan algn cach.
CONNECT Transforma la solicitud en una conexin a un tnel TCP/IP para facilitar la comunicacin segura (HTTPS) a travs de un
proxy HTTP no encriptado.
Descripcin
Accept:
Permite al cliente especificar los tipos de medios (MIME types) que son aceptables como respuesta. Ej.: Accept:
text/plain; text/html; application/html+xml . Un asterisco indica que todas las categoras o todos los medios
son aceptables (*/* se asume si no se especifica un atributo Accept). Un prmetro q=valor indica la calidad
aceptable, donde valor es un real entre 0.0 y 1.0; til especialmente en vdeo o ciertos formatos. Si el servidor no puede
responder con un formato aceptable, debe generar un mensaje con el status code 406 NOT ACCEPTABLE.
Host:
Permite especificar el servidor y el puerto que tiene el recurso solicitado, ya que la primera lnea (Request line) no incluye
estos valores y se necesitan para desambiguar en caso de servidores proxy u otros intermediarios. Es el nico atributo
obligatorio en HTTP/1.1. Ej.: Host: www.miservidor.com:8080 .
Referer:
Permite especificar el URL del recurso del cual se obtuvo el URL solicitado al servidor. Debera ser Referrer:, pero en el
estndar aparece como Referer:.
User
Agent:
Contiene informacin sobre el navegador o agente de usuario que solicita el recurso. Consta de varias parejas
mdulo/valor separadas por espacios y en orden de importancia. Todos los agentes de usuario deben proveer este
atributo. Ej.: User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0.1) Gecko/20100101
Firefox/5.0.1.
Tabla 1.4. Campos estndar en el HTTP Request header.
22/09/2015 11:52 a. m.
10 de 99
El status_code es un nmero y el reason_phrase es un texto corto escogido por el servidor web y comprensible para seres
humanos; el navegador no necesita analizarlo. El status_code es entero de tres dgitos, donde el primer dgito indica una de
las cinco clases de respuesta definidas por el estndar HTTP:
1. Informacin. La solicitud fue recibida y est siendo procesada.
2. xito. La solicitud fue recibida, entendida, aceptada y procesada exitosamente.
3. Redireccin. Se necesitan ms acciones del cliente para completar la solicitud.
4. Error del cliente. La solicitud es incorrecta por error de sintaxis o no se puede realizar.
5. Error del servidor. El servidor fall al procesar una solicitud aparentemente vlida.
Por ejemplo, el error 404 NOT FOUND indica que el cliente especific un URL de un recurso que no existe en el servidor. El
RFC 2616 de HTTP/1.1 define 41 status_codes, algunos de los ms comunes son los siguientes:
200 OK. La solicitud HTTP fue exitosa. Por ejemplo, si la solicitud fue un GET, la respuesta contendr el recurso
solicitado en el campo Message body; si la solicitud fue un POST, los datos enviados por el cliente fueron procesados
exitosamente.
204 NOT CONTENT. El servidor proces la solicitud exitosamente, pero no es necesario generar un recurso como
respuesta y por ende el campo Message body est vaco.
206 PARTIAL CONTENT. El servidor responde con un fragmento del recurso solicitado, tal como fue pedido por el cliente
web. Esto es de utilidad para continuar descargando un recurso incompleto o permitir varias descargas simultneas en
partes diferentes del mismo recurso. Esta funcionalidad es ampliamente explotada por los administradores de
descargas (download managers).
301 MOVED PERMANENTLY. El recurso ha sido movido a otro URL y el cliente debe obtener el nuevo recurso con una
nueva solicitud.
302 FOUND. No debera usarse. Normalmente se quiere decir 303.
303 SEE OTHER. El recurso est disponible en otro URL, el cual el cliente debe obtener con una solicitud nueva. Puede
fallado. La respuesta incluye un reto al usuario, el cual debe proveer un nombre de usuario y contrasea.
403 FORBIDDEN. La solicitud es vlida pero el servidor se niega a completarla, por ejemplo, tras varios intentos el
implementa.
503 SERVICE UNAVAILABLE. El servidor web no est disponible por sobrecarga o en mantenimiento. Normalmente una
condicin temporal.
Para revisar la lista completa de cdigos de estado HTTP con los que puede responder un servidor, consltese el RFC 2616.
1.2.4.7 Response header
El campo encabezado de respuesta HTTP (HTTP Response Header) permite al servidor enviar informacin adicional sobre
la respuesta al agente de usuario. Utilizan la misma notacin que los del campo encabezado de solicitud HTTP y tambin se
pueden extender mientras los agentes estn de acuerdo en ellos. Algunos se explican en la siguiente tabla.
Campo
Descripcin
ETag:
Contraccin de "Entity Tag". Es una cadena que permite identificar el estado del recurso, de tal forma que si se
hace una modificacin del recurso en el servidor, su ETag variar. Esto permite al cliente saber si su copia en el
cach est actualizada o ha variado en el servidor. Ej.: Etag: "239876f-4b8c-429fe67474a80" .
Location:
Permite al servidor indicarle al agente de usuario que el recurso solicitado ha sido movido a un nuevo URL. El
agente usuario debe entonces solicitar el nuevo recurso, lo que se conoce como una "redireccin".
Server:
Contiene informacin sobre el servidor web que genera la respuesta. Consta de varias parejas mdulo/valor
en orden de importancia para identificar al servidor. Ej.: Server: Apache/2.2.9 (Debian)
PHP/5.2.17-0.dotdeb.0.
22/09/2015 11:52 a. m.
11 de 99
Campo
Descripcin
Solicita al usuario autenticarse para acceder a un recurso en una respuesta 401 UNAUTHORIZED. Es seguido
WWW-Authenticate:
por el nmero de intentos permitidos. Ej.: WWW-Authenticate: 3.
Tabla 1.5. Campos estndar en el HTTP Response header.
Un visitante accede con su navegador a www.ejemplo.com. La interaccin entre el navegador web y el servidor web se aprecia
en el diagrama de secuencia de la Figura 1.4.
ind ex.html
O pera
Servidor web
img/ucr.png
Cliente
www.ejemplo.com
GET / HTTP/1.1
Host: www.ejemplo.c om
User-Agent: Opera/11.5
HTTP/1.1 200 OK
Content-type: text/html
Content-length: 296
Server: Apac he/2.2.19
<html><head><title>Desarrollo de
aplicaciones web</title>[...]</html>
HTTP/1.1 200 OK
Content-type: image/png
Content-length: 46236
Server: Apac he/2.2.19
<89>PNG^Z^@^@^@^MIHDR^@^
@^@<A1>^@^@^@<A8>^H^F[...]
Al escribir la direccin http://www.ejemplo.com/ el navegador contacta al "default gateway" que tenga configurado el
sistema operativo de la mquina local y le pide que le resuelva la direccin IP del dominio www.ejemplo.com. Al obtener la
direccin IP, el navegador establece una conexin TCP en el puerto 80 con www.ejemplo.com y ste acepta. A partir de este
momento se ha establecido una sesin HTTP; el navegador y el servidor web pueden intercambiar mensajes HTTP.
El navegador solicita el recurso que el usuario indic en el URL, en este caso es "/". Ensambla un mensaje HTTP Request
con el mtodo GET, escribe algunos campos de encabezado (HTTP Request Header fields) y un cambio de lnea. Lo enva al
servidor.
El servidor recibe la solicitud HTTP y de acuerdo a su configuracin local, obtiene que el recurso "/" equivale al archivo
index.html. Ensambla una respuesta HTTP (HTTP Response message) con el status code 200 indicando que el recurso fue
encontrado y la solicitud se proces exitosamente. Agrega unos campos de encabezado de respuesta (HTTP Response
22/09/2015 11:52 a. m.
12 de 99
Header fields) y anexa el contenido del recurso index.html literalmente en el campo Message body. Lo enva al cliente.
El navegador recibe el mensaje de respuesta HTTP y viendo que la solicitud fue exitosa, extrae el recurso index.html guiado
por los campos de encabezado HTTP. Almacena el recurso en su cach e inicia el anlisis (parsing) y despliegue (rendering)
del recurso en la ventana del usuario. Al analizar la lnea 4 del index.html, el navegador se percata de que necesita otro
recurso para presentarlo en la pgina, y ensambla otra solicitud al servidor, de la misma forma que hizo con index.html,
pero esta vez por img/ucr.png.
El servidor web recibe la nueva solicitud y la procesa de la misma forma que hizo previamente con index.html. El recurso
tambin existe. La nica diferencia es que img/ucr.png es un recurso binario, de ah la importancia de los campos del
encabezado que ayudarn al navegador a procesar el recurso adecuadamente. El servidor enva el mensaje de respuesta.
El navegador recibe el mensaje y al ver que es exitoso, agrega el recurso en su cach y guiado por los campos del
encabezado del mensaje, interpreta el contenido binario como una imagen PNG y la coloca en su lugar dentro de la
ventana. Al analizar la lnea 5 del documento index.html (Listado 1.1), se percata de que necesita tambin el recurso
img/ecci.png. Ensambla una nueva solicitud GET y la enva al servidor como hizo anteriormente.
El servidor web recibe la solicitud y trata de localizar el recurso. Al notar que no se encuentra en su sistema de archivos,
construye una respuesta HTTP con status code 404 Not Found, indicando que el agente del usuario solicit un recurso
errneo. En el cuerpo del mensaje agrega un texto ms explicativo y en los campos del encabezado HTTP detalles de cmo
interpretar este texto. Lo enva al cliente.
El navegador recibe el mensaje 404 Not Found. Al no obtener un recurso para desplegar (render), opta por dibujar un
rectngulo genrico indicando la ausencia y rellena con el texto alternativo que se encuentra en el documento index.html.
Contina de esta forma analizando y desplegando el recurso index.html hasta alcanzar su final.
22/09/2015 11:52 a. m.
13 de 99
(los estilos, si se usar una metfora, etc.), las convenciones (los nombres de los archivos, reglas de escritura del cdigo
fuente, etc.).
Sin un buen diseo el programador se sentar frente a la computadora sin saber cmo empezar el sitio web, ni qu
secciones tendr, ni cules de ellas tendrn pginas estticas o sern programadas, etc. La importancia de la fase de diseo
web es tal que libros completos atienden el tema, como "Web Style Guide" de Patrick J. Lynch y Sarah Horton, cuyo texto
completo se encuentra disponible en lnea gratuitamente.
22/09/2015 11:52 a. m.
14 de 99
Normalmente estos buscadores proveen algn mecanismo para solicitarles que consideren incluir un dominio en sus ndices.
Aunque el sitio web sea incluido en los ndices de los buscadores, es muy probable que no aparezca entre los primeros
resultados de una consulta. Esto se puede mejorar incrementando la "popularidad" del sitio. Los buscadores miden qu tan
popular es un recurso en proporcin a la cantidad de enlaces que encuentran hacia dicho recurso en otros dominios. Por
eso, enlazar el sitio web en diarios, noticias, listas de correo u otros medios puede ayudar.
Una alternativa ms es invertir en publicidad local o internacional. Incluso se puede costear un lugar privilegiado en los
resultados de los buscadores ms populares.
2.1 Conceptos
Los seres humanos tienen diversas necesidades de informacin, y cuando sta se debe almacenar en la computadora, se
suele hacer en forma de bases de datos o documentos digitales. Las bases de datos restringen en alguna medida la
representacin de informacin del mundo real a una estructura formalmente definida que puede ser eficientemente
manipulada por el computador. Los documentos son menos estrictos por lo que pueden representar casi cualquier tipo de
informacin del mundo real, pero tal libertad limita el poder de manipulacin del computador. El XML es un lenguaje formal
que busca las ventajas de ambos: la representacin flexible de informacin en forma de documentos que pueden ser
manipulados aprovechando el poder del computador.
Charles Goldfarb, el principal autor del SGML, indica que XML sirve para la representacin digital de documentos.
Representar digitalmente un documento implica transformarlo en algn tipo de cdigo legible por la computadora para que
sta sea capaz de almacenarlo, procesarlo, buscarlo, transmitirlo, mostrarlo e imprimirlo [Gold99]. La estrategia consiste en
separar los datos del documento de su presentacin y adems, describir la estructura lgica y fsica que sigue el documento.
La presentacin de un documento es la percepcin que tiene el ser humano de l, que tpicamente es impresa en papel o
en una pantalla [Gold99]. La estructura del documento describe la distribucin y orden de los componentes del
documento. Los componentes varan dependiendo del tipo de documento. Por ejemplo, un libro suele tener como
componentes: portada, ndice, partes, captulos, secciones, prrafos, oraciones, palabras, ttulos, notas, etc. En terminologa
XML estos componentes reciben el nombre de elementos. El Listado 2.1 muestra un ejemplo de un posible libro en
notacin XML.
1. <?xml version="1.0" encoding="UTF-8"?>
2. <!DOCTYPE book SYSTEM "book.dtd">
3.
4. <book name="AplicacionesWeb" version="1.0">
5.
<title>Aplicaciones web</title>
6.
<authors>
7.
<author name="Jeisson" percent="100">
8.
<fullname>Jeisson Hidalgo-Cspedes</fullname>
9.
<email>jeissonh@gmail.com</email>
10.
</author>
11.
</authors>
12.
13.
<chapter name="Preliminar" type="prelims">
14.
<section name="Prologo">
15.
<title>Prlogo</title>
16.
<p>Este documento contiene un resumen de temas que servirn de
17.
apoyo a los estudiantes del curso CI-2413 impartido...</p>
18.
</section>
19.
<section name="Agradecimientos" type="acknowledgements" author="Jeisson">
20.
<title>Agradecimientos</title>
22/09/2015 11:52 a. m.
15 de 99
21.
<p>Quiero agradecer en primer lugar, a usted, que con sus ojos
22.
da vida a estas inanimadas palabras pintadas en...</p>
23.
</section>
24.
</chapter>
25.
26.
<chapter name="Introduccion">
27.
<title>Introduccin a la tecnologa web</title>
28.
<p>De todas las aplicaciones que se han construido sobre Internet...</p>
29.
<p>Su popularidad puede deberse a su "facilidad de uso" y...</p>
30.
31.
<section name="HistoriaWeb">
32.
<title>Historia</title>
33.
<p>La web fue conceptualizada en un artculo de 1989 Tim Berners-Lee</p>
34.
</section>
35.
</chapter>
36. </book>
Listado 2.1. Ejemplo de un libro hipottico en XML.
Otro concepto presente en la estructura de un documento XML es el de entidad. Una entidad representa cualquier trozo de
texto, desde un carcter, un prrafo, un archivo o todo un libro. Las entidades tienen nombre el cual puede utilizarse en
cualquier parte del documento al insertar una referencia de entidad, la cual es sustituida por la entidad misma cuando el
documento es procesado. Las entidades funcionan de forma similar a las macros de los procesadores de palabras [Gold99].
Por ejemplo la referencia a la entidad < en un documento XML se reemplaza por el smbolo "<".
Las entidades permiten separar un todo en partes fsicas que facilitan la manejabilidad o ciertos procesos, pero tambin se
pueden manipular como un todo cuando sea necesario. Por ejemplo, es tedioso imprimir un manual HTML que est
segmentado en cientos de archivos .html unidos dbilmente por enlaces (links). En XML, la informacin de cada archivo
.html se escribira como una entidad y en el archivo que represente el todo, contendr referencias a las entidades
anteriores, el cual puede ser impreso con facilidad.
Las entidades pueden representar informacin en otra notacin que no es XML, por ejemplo, imgenes, archivos de audio,
archivos de vdeo, texto puro, HTML, etc. Estas entidades reciben el nombre de entidades no analizables sintcticamente.
Se dice que las entidades describen la estructura fsica y los elementos la estructura lgica de los documentos XML. La
estructura lgica (elementos) y fsica (entidades) se representa dentro del documento XML agregando el marcado, el cual se
delimita de los datos de carcter encerrando la descripcin de los elementos dentro de parntesis angulares (< y >), que
se conocen como etiquetas y las referencias a entidades entre el signo & y el punto y coma (;). Es decir, el texto
encerrado dentro de estos cuatro caracteres se conoce como marcado, lo restante como datos de carcter. La
combinacin del marcado ms los datos de carcter forman el texto XML [Gold99].
Es sabido que las cartas, tesis, guiones y las guas telefnicas son documentos que tienen una estructura muy diferente. Es
decir, poseen elementos distintos, cada uno con su propia distribucin y orden. Se dice que son tipos de documentos
distintos. En XML cada tipo de documento se define en una notacin formal que plasma su estructura llamada definicin de
tipo de documento (DTD, Document Type Definition). A modo de ejemplo, la lnea 2 del listado Listado 2.1 declara que el
tipo de documento es un libro.
Se puede pensar en un DTD como una clase en programacin orientada a objetos, mientras que un documento XML que sea
de ese tipo de DTD es como un objeto que instancia esa clase. El objeto documento XML debe cumplir a cabalidad con la
estructura descrita en su DTD, cuando esto ocurre, se dice que el documento es de tipo vlido o simplemente vlido, de lo
contrario, se dice que el documento es de tipo no vlido o simplemente no vlido (pero no se usa el trmino "invlido")
[Gold99].
Un documento XML puede no tener un tipo de documento definido, es decir, carece o no cumple con un DTD, por lo que es
un documento no vlido pero puede respetar la sintaxis XML, en tal caso se dice que slo es un documento bien formado
(well formed). Los documentos bien formados pero no vlidos (no cumplen un DTD) suelen utilizarse para documentos
pequeos que deben escribirse de forma rpida. Los documentos vlidos siempre estn bien formados y son necesarios
cuando son muy extensos o deben procesarse por algn sistema computacional [Gold99].
22/09/2015 11:52 a. m.
16 de 99
[Gold99].
Varios espacios en blanco, tabuladores y cambios de lnea se ignoran a menos que sean cadenas literales, las cuales se
escriben entre comillas dobles (") o simples (') o una combinacin de ambas, pero con la restriccin de que la comilla que
cierra la cadena debe ser del mismo tipo de la que abre. Esto implica que un software que procese el listado Listado 2.1,
deber ignorar los cambios de lnea y espacios en blanco que rodean al prrafo en las lneas 16 y 17.
Los documentos XML constan de dos partes: encabezado (head) y cuerpo (body). El encabezado de un documento XML
recibe el nombre de prlogo de documento y almacena informacin que describe al cuerpo del documento, como la
versin de XML, el tipo de documento (DTD) al que pertenece, la codificacin y otros. El cuerpo del documento XML recibe el
nombre de instancia de documento, que contiene los datos reales del documento.
Los elementos se pueden anidar, formando un rbol. Los elementos dentro de otros se llaman elementos hijos y a los
contenedores, elementos padres. Slo puede existir un nico elemento raz, tambin llamado elemento documento,
que contiene a todos los dems [Marc00]. En el listado Listado 2.1 el elemento con identificador book es elemento raz.
Los elementos se describen utilizando etiquetas. Una etiqueta es el marcado entre un par de signos menor que y mayor
que. Un elemento es la combinacin de una etiqueta de inicio (que puede tener atributos), un contenido opcional y una
etiqueta de cierre, es decir
<identificador_etiqueta_inicio atributos="valor">
contenido
</identificador_etiqueta_cierre>
Un elemento tiene dos etiquetas, una de inicio y otra de cierre (o fin). La etiqueta de inicio se compone de un carcter
menor que (<), un identificador_etiqueta_inicio que es un simple identificador y debe respetar las restricciones de los
identificadores; seguido por cero o ms parejas atributo="valor"; y un carcter de mayor que (>).
La etiqueta de cierre o etiqueta de fin consta de los caracteres menor que (<) y un slash (/), luego un
identificador_etiqueta_cierre que obligatoriamente debe ser el mismo identificador que el de la etiqueta de inicio del
elemento y un carcter de mayor que (>). La etiqueta de cierre nunca tiene atributos.
El contenido del elemento puede ser nulo o texto XML, es decir, datos de carcter, otros elementos (y por ende etiquetas)
o ambos. Si un elemento no tiene contenido se dice que es un elemento vaco, y se puede escribir en cualquiera de las dos
siguientes formas:
<id_elemento atributos="valor"></id_elemento>
<id_elemento atributos="valor"/>
La segunda de las formas anteriores consta de una sola etiqueta llamada etiqueta vaca, la cual finaliza en un slash (/)
indicando que el elemento ha terminado. Es poco comn encontrar etiquetas vacas sin atributos.
Si un elemento tiene contenido (no es vaco) y se omite alguna de las etiquetas (la de inicio o la de fin) el procesador XML
deber alertar de que el documento no est bien formado.
Debe quedar claro que las etiquetas no son elementos. Las etiquetas inician con un '<' y terminan con un '>', lo dems no
son etiquetas [Gold99]. Los elementos tienen etiquetas y contenido. Los elementos se escriben en el documento XML y son
instancias de los tipos de elementos, los cuales se declaran en la definicin del tipo de documento (DTD).
Los elementos pueden tener atributos que son una forma de incorporar caractersticas o propiedades a los elementos de un
documento [Gold99, 353]. Un atributo se compone de un identificador, un signo de igual (=) y un valor entre comillas
(dobles, simples o una combinacin de ambas).
22/09/2015 11:52 a. m.
17 de 99
La declaracin DOCTYPE indica el tipo de documento y adems instruye al procesador de XML dnde encontrar la definicin
del tipo de documento (DTD), el cual puede estar escrito en el mismo documento XML o puede encontrarse en una entidad
externa (un archivo en disco o red) o una combinacin de ambas. Lo ms comn es que se encuentre en un recurso
externo, como se hizo en la segunda lnea del listado Listado 2.1, la cual instruye al procesador XML que el tipo de
documento est en el archivo "book.dtd" en la misma ubicacin que el documento XML. La palabra SYSTEM indica al sistema
que busque el recurso especificado en el URI (Universal Resource Identifier) que le contina. Ms adelante se estudiar la
nomenclatura de un DTD.
El identificador del elemento que contina inmediatamente despus de <!DOCTYPE, por ejemplo, book en el listado Listado
2.1, indica al procesador XML a partir de qu elemento del DTD se debe incluir, es decir, slo se incluye el subrbol cuya raz
es precisamente ese elemento.
&
&
<
<
>
>
'
'
"
"
Aunque el uso de entidades predefinidas parece sencillo, hace que el documento XML se vuelva difcil de leer para el autor,
en especial cuando se usan repetidamente, como ocurre al escribir segmentos de cdigo fuente; por eso se crearon las
secciones CDATA; las cuales indican al procesador XML que no interprete una parte del texto aunque contenga marcado,
es decir, que lo trate como datos de carcter (character data, de ah la contraccin CDATA). La sintaxis de una seccin de
datos de carcter es
<![CDATA[ contenido ]]>
En el contenido puede aparecer cualquier cadena de texto, excepto la que cierra la seccin CDATA (]]>) llamada CDEnd. La
lnea 29 del listado Listado 2.1 usa dos entidades preestablecidas. Este mismo elemento pudo haberse escrito con una
seccin CDATA como
<p><![CDATA[
Su popularidad puede deberse a su "facilidad de uso" y...
]]></p>
Los comentarios son cadenas de caracteres que no son parte de los datos de carcter, es decir, es parte del marcado pero
que debe ser ignorado por el procesador XML. Permiten al autor hacer anotaciones que le ayuden a comprender o recordar
partes del documento. El texto del comentario se introduce entre los caracteres inicio de comentario (<!--) y final de
comentario (-->). Por ejemplo
<!-- Esto es un comentario -->
Todo el texto dentro del inicio y fin de comentario ser ignorado, incluyendo los caracteres de marcado (menor que,
ampersand, comillas, etc.), excepto la secuencia de cierre del comentario (-->).
22/09/2015 11:52 a. m.
18 de 99
<!ENTITY % SectionType
"forework|preface|acknowledgements|dedication|contents">
<!ELEMENT book (title, authors, front-cover?, chapter+, back-cover?)>
<!ATTLIST book
name ID #REQUIRED
version CDATA #REQUIRED>
<!ELEMENT title (#PCDATA)>
<!ELEMENT authors (author+)>
<!ELEMENT author (fullname, email?)>
<!ATTLIST author
name ID #REQUIRED
percent CDATA #IMPLIED>
<!ELEMENT fullname (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT front-cover EMPTY>
<!ATTLIST front-cover
img CDATA #REQUIRED>
<!ELEMENT chapter (title?, (p|section)+)>
<!ATTLIST chapter
name ID #REQUIRED
type (prelims|contents) "contents">
<!ELEMENT p (#PCDATA|em|strong|code)*>
<!ELEMENT em (#PCDATA)>
<!ELEMENT strong (#PCDATA)>
<!ELEMENT code (#PCDATA)>
<!ELEMENT section (title?, (p|section)+)>
<!ATTLIST section
name ID #REQUIRED
type (%SectionType;) "contents"
author IDREF #IMPLIED>
<!ELEMENT back-cover EMPTY>
<!ATTLIST back-cover
img CDATA #REQUIRED>
22/09/2015 11:52 a. m.
19 de 99
El <!ELEMENT inicia la declaracin de un tipo de elemento. El IdElemento es el identificador que aparece en sus etiquetas.
Debe ser nico en el DTD y respetar las restricciones de los identificadores expuestas en la seccin Conceptos XML. La
EspecContenido se refiere a la especificacin de contenido, que indica qu objetos pueden figurar en el contenido del
elemento, hay cuatro posibilidades [Gold99]:
Tipo
Descripcin
EMPTY
Impide que el elemento tenga contenido y por tanto sus etiquetas son vacas. Ejemplo: front-cover en la lnea 22 en el
DTD del listado prettyprint linenums lang-xml 2.2.
ANY
Puede contener cualquier elemento o carcter, lo cual no se recomienda ya que no es estructurado. Pueden ser tiles
cuando se est escribiendo el DTD para lograr que los documentos sean vlidos mientras se est refinando dicho DTD.
elementcontent
Slo puede contener los subelementos listados dentro de parntesis en la especificacin de contenido. Por ejemplo, la
lnea 26 del listado prettyprint linenums lang-xml 2.2 indica que los elementos chapter slo pueden tener un ttulo
opcional y varios prrafos o secciones.
mixedcontent
Permite al elemento contener subelementos, datos de carcter (#PCDATA) o ambos, como ocurre con el elemento de
prrafo p en la lnea 31 del listado prettyprint linenums lang-xml 2.2.
Especificacin de contenido de elementos XML.
Cuando un elemento tiene subelementos (o elementos hijos) en el contenido (ltimos dos casos de la lista anterior), es
necesario especificar un modelo de contenido (content model), que establece el orden y nmero de apariciones de los
subelementos.
El orden de los elementos hijos se establece con los caracteres coma, barra vertical (|) y parntesis. Una secuencia de
subelementos separados por coma indica que tales subelementos deben aparecer y en el mismo orden. La barra vertical
indica que debe aparecer slo uno de los dos subelementos que estn en sus extremos. Los parntesis agrupan partculas de
contenido que son tratadas como unidades por los operadores anteriores, lo que permite combinarlos.
El nmero de apariciones de los subelementos se especifica con los indicadores de frecuencia que se escriben al final del
subelemento, sin espacios en blanco y son tres. El signo de interrogacin (?) indica que el elemento hijo es opcional, es
decir, puede o no puede aparecer. El asterisco (*) indica que el subelemento puede aparecer 0 ms veces (opcional y
repetible). El signo de ms (+) indica que el subelemento puede debe aparecer 1 o ms veces (necesario y repetible)
[Gold99].
El <!ATTLIST indica que se va a declarar la lista de atributos del elemento identificado por IdElemento. IdAtt indica el
nombre del atributo; debe ser un identificador vlido y no es obligatorio que sea nico en el documento. El tipo del atributo
TipoAtt puede ser alguno de los siguientes
Tipo
Descripcin
CDATA
NMTOKEN
Name token. Slo permite letras, nmeros y algunos caracteres especiales, como los que se utilizan para declarar
identificadores, pero no obliga a que sea nico en el documento.
NMTOKENS
(a|b|c|d) Enumerados. La lista de valores permitidos se escribe dentro de parntesis y separados por barras verticales (|), por
ejemplo el atributo type en la lnea 29 del listado prettyprint linenums lang-xml 2.2.
ID
Identificador. Declara que el atributo es un identificador nico, es decir, su valor debe cumplir con las restricciones de los
identificadores y en el documento XML no puede haber dos o ms atributos con el mismo valor.
IDREF
Referencia a un identificador. Declara que el atributo tiene como valor una referencia a un identificador existente. Su
valor puede repetirse muchas veces en el documento XML pero debe respetar las restricciones de los identificadores.
ENTITY
Referencia a una entidad (o atributos de entidad). El valor del atributo debe ser el nombre de una entidad existente en el
documento XML.
Tipos de atributos en un DTD.
El DefaultValue en la declaracin de la lista de atributos indica si el atributo se puede omitir o no, y el valor por defecto en
caso de que se omita. Puede tomar tres variantes:
Tipo
Descripcin
Indica que el atributo es requerido y no se puede omitir, por tanto no tiene un valor por defecto. Son ejemplos name y
#REQUIRED
version de book en el listado prettyprint linenums lang-xml 2.2.
value
Un valor que est en el dominio de valores permitido por el tipo de atributo. Indica que ese ser el valor que el
procesador XML tome si el autor no especifica uno en el documento. Por ejemplo, segn la lnea 29 del listado prettyprint
linenums lang-xml 2.2, si el autor no especifica el tipo del captulo, el procesador XML asumir que se trata de un
captulo de contenido y no uno preliminar.
Valores por defecto de atributos en un DTD.
22/09/2015 11:52 a. m.
20 de 99
Tipo
#IMPLIED
Descripcin
Permite al autor omitir el valor del atributo pero sin forzar a escribir un valor por defecto determinado. El procesador XML
asignar algn valor que considere adecuado o lo ignora.
Hay tres criterios para clasificar entidades y por tanto, 8 combinaciones de las cuales 5 son vlidas. Los criterios son
Analizables o no analizables
Internas o externas
Generales o parmetro
Las entidades cuyo contenido es texto XML que debe ser analizado por el procesador XML reciben el nombre de entidades
analizables (parsed entities). Si el contenido de la entidad es cdigo ajeno a XML (como imgenes o texto puro) que no
debe analizarse, se denomina entidades no analizables. Las entidades no analizables terminan en NDATA seguido por un
indicador del formato, como ocurre con cedula en el listado prettyprint lang-xml 2.13. Las entidades que no se declaran con
NDATA son analizables.
Las entidades externas son aquellas cuyo contenido est en un recurso fuera de la declaracin de la entidad, y por tanto
debe proveerse un URL hacia ese recurso precedido por la palabra SYSTEM o PUBLIC, como ocurre con cap01 y cedula en el
listado prettyprint lang-xml 2.13. Mientras que el contenido de las entidades internas est escrito en la misma declaracin
de la entidad entre comillas, como ocurre con adn y frase en el listado prettyprint lang-xml 2.13.
Reciben el nombre de entidades generales aquellas que se pueden referenciar en cualquier lugar del documento XML,
como ocurre con &adn; del listado prettyprint lang-xml 2.13 y las entidades predefinidas, como & que son declaradas
por el procesador XML. Las entidades que slo se pueden referenciar dentro del DTD se conocen como entidades
parmetro. Es decir, son de uso exclusivo del DTD y no se pueden referenciar desde el documento XML. Se declaran
anteponiendo un % y se referencian usando la notacin %IdEntidad; en lugar de &IdEntidad; como ocurre con %SectionType;
en las lneas 1 y 40 del listado prettyprint lang-xml 2.9.
<!ENTITY
<!ENTITY
<!ENTITY
<!ENTITY
<!ENTITY
Los identificadores externos hacen referencia a informacin que se encuentra fuera de la entidad en la que tienen lugar
[Gold99, p404]. Existen dos tipos, los identificadores de sistemas (SYSTEM) y los identificadores pblicos (PUBLIC).
Los identificadores de sistemas utilizan la palabra clave SYSTEM y se refieren a un objeto por su localizacin utilizando un
22/09/2015 11:52 a. m.
21 de 99
URI (Universal Resource Identifier). Pueden ser direcciones absolutas o relativas a la ubicacin de la entidad documento que
contiene el identificador. La siguiente declaracin referencia el recurso "http://www.serv.com/dir/cap02.xml":
<!ELEMENT cap02 SYSTEM "http://www.serv.com/dir/">
Los identificadores pblicos utilizan nombres declarados pblicamente para referirse a la informacin. Estos nombres
deben ser nicos en el mundo. Tienen cuatro partes separadas por dos slash (//). La primera parte es un carcter de suma
(+) si la organizacin que publica el recurso est registrada en el ISO, sino es un carcter de menos (-), lo cual ocurre con
mayor frecuencia. La segunda parte es el dueo del recurso. La tercera parte es la descripcin del recurso, que permite
espacios en blanco. La ltima parte es el lenguaje en que est escrito el recurso [Marc00]. Los dos siguientes ejemplos de
declaraciones de tipo de documento emplean identificadores pblicos. El primero de ellos es ficticio.
<!DOCTYPE book
PUBLIC "-//ECCI-UCR//DTD book//EN"
"http://www.ecci.ucr.ac.cr/dtd/book.dtd">
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
22/09/2015 11:52 a. m.
carcter por carcter, identificando elementos, atributos, datos de carcter, referencias de entidad, etc. Cada vez que el
parser identifica uno de esos componentes lxicos, acta como si fuese un evento y realiza un llamado a la aplicacin para
que lo atienda, pasndole como parmetros los lexemas identificados. SAX es un enfoque bastante rudimentario pero es
muy eficiente.
El segundo API estndar es el Document Object Model (DOM) que se basa en el modelo de documento, esto es, el parser
recorre el documento XML construyendo una estructura jerrquica compuesta de nodos, los cuales pueden ser elementos,
atributos o datos. Cuando se ha terminado de analizar el documento XML, el rbol de objetos nodo estar construido y se
pasar como parmetro a la aplicacin, la cual podr utilizarlo para sus propios fines [Gars02].
documento XML
Para transformar un documento XML a otro documento de texto, como (X)HTML, CSV (Comma-Separated Values file), texto
puro u otro tipo de documento XML; el autor puede escribir una hoja de estilos, que es un conjunto de instrucciones o reglas
en notacin XSLT (Extensible Stylesheet Language Transformations) que indican cmo se debe transformar cada pieza de
informacin (nodo) presente en el documento XML. Un software llamado Procesador XSLT (XLST Processor) toma estos
dos documentos por entrada, aplica las reglas de la hoja de estilos al documento XML y el resultado es el documento
transformado. Este proceso se ilustra en la figura siguiente.
libro.xml
libro_web.xsl
hoja de estilos
Procesador XSLT
libro.html
documento transformado
22 de 99
En general el proceso de transformacin es como sigue. El procesador XSLT analiza el documento XML y genera un rbol de
nodos conocido como DOM (Document Object Model). Luego procesa la hoja de estilos. Cada regla definida en ella afecta a
uno o varios nodos del documento. Una regla consta de dos partes: una consulta (query) que sirve para identificar a cules
nodos debe aplicarse, y una operacin que debe efectuarse en esos nodos. La consulta puede asemejarse a otros lenguajes
de consulta como SQL (Structured Query Language), pero emplea una notacin especial llamada XPath, mencionada
anteriormente. La operacin consta de texto literal que aparecer en la salida o de trozos del elemento al que se le est
aplicando la regla. La concatenacin de todas las salidas constituye el documento transformado que desea el autor.
La forma de invocar al procesador XSLT vara dependiendo de la implementacin. Las hay en forma de ejecutables en lnea
de comandos, como bilbiotecas compartidas (.so, .dll), incorporados en un navegador o una mezcla de ellas. Por ejemplo,
libxslt del proyecto GNOME puede usarse como una biblioteca compartida desde cualquier programa, o en lnea de
comandos como se muestra en el siguiente ejemplo:
xsltproc libro_web.xsl libro.xml > libro.html
La mayora de navegadores web actuales implementan un procesador XSLT internamente, sin embargo no hay forma de
indicarles en un URL la ubicacin del documento XML y la hoja de estilos simultneamente. Pero si el autor indica en el
prlogo del documento XML cul hoja de estilos quiere que se aplique, el navegador har la trasformacin y tratar de
desplegar (rendering) el resultado directamente. Un documento XML declara su hoja de estilos con la instruccin de
procesamiento xml-stylesheet, por ejemplo:
1. <?xml version="1.0" encoding="UTF-8"?>
2. <!DOCTYPE book SYSTEM "book.dtd">
3. <?xml-stylesheet href="book_web.xsl" type="text/xsl"?>
22/09/2015 11:52 a. m.
23 de 99
4.
5. <book name="MiLibro" version="1.0">
6.
<!-- ... -->
7. </book>
22/09/2015 11:52 a. m.
24 de 99
22/09/2015 11:52 a. m.
25 de 99
diferencia es que un documento web debe seguir estrictamente la sintaxis de (X)HTML. Al hacerlo, cualquier software
(X)HTML podr manipular el documento, sea un navegador, un programa de diseo, un motor de bases de datos y hasta el
mismo procesador de palabras mencionado anteriormente. Dado que el navegador es el ms comn, se usar en este texto
por claridad en lugar de software (X)HTML.
Un documento web se compone de cuatro partes: la declaracin del tipo de documento, el elemento documento, el
encabezado y el cuerpo. El listado prettyprint linenums lang-html 3.1 muestra un ejemplo de documento web con estas
cuatro partes. Los comentarios utilizan la misma notacin de XML y pueden aparecer en casi cualquier lugar del documento.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Variation
strict
HTML
4.01 transitional
frameset
strict
transitional
frameset
1.1
--
5.0
--
1.0
XHTML
(X)HTML
Document type
<!DOCTYPE html>
Tipos de documento (X)HTML de acuerdo a su versin y variacin
Aunque en HTML es opcional, siempre es conveniente incluir el tipo de documento; y a menos de que se est usando
(X)HTML5 es difcil memorizarlos. Por eso los autores histricamente han tenido una fuente de la cual copiar y pegar los
tipos de documentos en sus creaciones, o confiar en un programa de diseo web que haga el trabajo automticamente.
Si se omite la declaracin del tipo de documento, la mayora de navegadores entran en "quirks mode", un modo de
compatibilidad para poder desplegar pginas web obsoletas que contienen errores o "quirks", con resultados dependientes
del navegador. Si la declaracin del tipo de documento est presente, el navegador entra en modo estndar, y si el
documento es vlido, el comportamiento debera ser homogneo entre navegadores.
El W3C ofrece varias herramientas gratuitas para asegurar la calidad (QA, Quality Assurance) de un sitio web. Entre ellas el
autor puede someter cualquier documento al W3C's Unified Validator (Unicorn) y recibir retroalimentacin de si est bien
formado, se conforma al tipo de documento que tiene declarado, no tiene enlaces rotos y los estilos que usa son vlidos.
Dado que XHTML es una aplicacin XML, todo documento XHTML debe iniciar con la especificacin XML como se ve en el
cdigo de abajo. El W3C recomienda esta prctica, sin embargo, algunas versiones antiguas de navegadores pueden
confundirse y entrar errneamente en "quirks mode", por lo que muchos autores omiten la especificacin XML en sus
documentos XHTML.
1.
2.
3.
4.
5.
6.
Al omitir la declaracin XML se pierde la oportunidad de informar sobre la codificacin del documento. Como un rodeo, los
22/09/2015 11:52 a. m.
26 de 99
autores lo hacen en el encabezado (X)HTML con un elemento de metainformacin, como se hizo en la lnea 6 del listado
prettyprint linenums lang-html 3.1.
Descripcin
id
Un nombre que identifica de forma nica a un elemento, de tal forma que se le puede hacer referencia posteriomente, en
especial en hojas de estilo y programas de JavaScript.
class
Sirve para agrupar varios elementos bajo un identificador comn. A todos los elementos de una misma clase se les puede
aplicar estilos o acceder desde un programa de JavaScript. Por su parte, un elemento puede pertenecer a varias clases, las
cuales se separan por espacios en blanco en el valor de este atributo.
Indica el idioma en el que se encuentra el contenido del elemento. Su valor es un cdigo de idioma en el estndar
lang
dir
22/09/2015 11:52 a. m.
27 de 99
En esta seccin se presentarn los elementos ms comunes para estructurar el texto del documento web: encabezados de
secciones (ttulos), prrafos, texto preformateado, texto estructurado y listas de elementos.
3.2.2 Prrafos
Un prrafo en (X)HTML se escribe con el elemento p como se aprecia en el listado prettyprint linenums lang-html 3.5.
Aunque en HTML es opcional cerrarlo, es recomendable siempre hacerlo. A travs de hojas de estilo se puede controlar el
espaciado entre prrafos, la sangra y otros formatos. No escriba prrafos vacos <p></p> para tratar de dejar espacio en
blanco en el documento, la especificacin (X)HTML recomienda al navegador ignorar estos elementos.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
22/09/2015 11:52 a. m.
28 de 99
31.
32.
33.
34.
35.
abbr
Descripcin
Indica una abreviatura, ej.: WWW, HTTP, etc., PhD. Son siglas o palabras reducidas.
acronym Indica un acrnimo, ej.: sonar, codec, JSON. Son abreviaturas que se leen como si fueran una palabra normal.
cite
code
dfn
em
Indica nfasis.
kbd
samp
strong
var
Los dos elementos de frase de uso ms comn son em y strong. Normalmente los navegadores los despliegan en itlicas y
negritas respectivamente, pero se puede alterar con hojas de estilo. Los dems elementos de frase estn orientados a
documentos tcnicos. El listado prettyprint linenums lang-html 3.6 muestra el uso de alguno de estos elementos.
1. <p>
2.
Se dice que <em>las entidades</em> describen la <strong>estructura fsica</strong>
3.
y <em>los elementos</em> la <strong>estructura lgica</strong> de los documentos
4.
<abbr title="Lenguaje de marcado extensible (eXtensible Markup Language)">XML</abbr>.
5.
La estructura lgica (elementos) y fsica (entidades) se representa dentro del
6.
documento <abbr title="Lenguaje de marcado extensible (eXtensible Markup Language)">
7.
XML</abbr> agregando <strong>el marcado</strong>, el cual
8.
se delimita de <em>los datos de carcter</em> encerrando la descripcin de los
9.
elementos dentro de parntesis angulares ("<code><</code>" y "<code>></code>"),
10.
que se conocen como <dfn>etiquetas</dfn> y <em>las referencias a entidades</em> entre
11.
el signo "<code>&</code>" y el punto y coma ("<code>;</code>"). Es decir, el
12.
texto encerrado dentro de estos cuatro caracteres se conoce como <dfn>marcado</dfn>,
13.
lo restante como <dfn>datos de carcter</dfn>. La combinacin del <em>marcado</em>
14.
ms los <em>datos de carcter</em> son el <dfn>texto XML</dfn> [Gold99].
15. </p>
22/09/2015 11:52 a. m.
29 de 99
Todos los elementos de frase tienen un atributo title, en el cual se puede escribir informacin adicional que aparece
cuando hay cierta interaccin con el elemento, normalmente un "tooltip" cuando el puntero del ratn pasa sobre ellos. Esto
es til para expandir el significado de las abreviaturas y acrnimos sin tener que incluir estas definiciones explcitamente en
el texto cada vez que se quiere usar la abreviatura. Ntese que esto se hizo en el listado prettyprint linenums lang-html 3.6
para la abreviatura "XML" que aparece dos veces, lo que genera redundancia de cdigo. Tericamente esta redundancia se
puede evitar en XHTML definiendo entidades generales en el parmetro interno del tipo de documento, sin embargo, los
navegadores actuales las ignoran, por lo que la mayora de autores prefieren hacer algn tipo de programacin del lado del
servidor antes de despachar la pgina web.
Los elementos sub y sup sirven para declarar subndices y superndices respectivamente. Aunque tienen utilidad matemtica
y en otras notaciones cientficas, realmente se mantienen en la recomendacin para otros textos. Ejemplos:
Texto
Cdigo (X)HTML
3.2.4 Listas
(X)HTML permite definir listas de temes. Las hay en tres tipos: listas ordenadas, listas no ordenadas, y listas de
definiciones. Las tres se pueden anidar. El siguiente listado muestra un ejemplo de los tres tipos de listas y su anidamiento:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
3.3 Enlaces
Un enlace es un mecanismo que permite acceder desde un documento web a otro documento web o cualquier otro recurso
(un archivo de sonido, imagen, pelcula, ejecutables, correos electrnicos, etc). Se escriben con el elemento a y su sintaxis
bsica es como sigue:
22/09/2015 11:52 a. m.
30 de 99
El valor del atributo href (contraccin de hypertext reference) es un URL hacia el recurso que se quiere enlazar. El
contenido del enlace puede ser cualquier cosa, pero tpicamente se usa un texto o una imagen. El navegador permitir al
usuario accionar el contenido del enlace, por ejemplo, haciendo click sobre l. Cuando esto ocurre, el navegador trata de
mostrar el recurso apuntado por el atributo href en la misma ventana donde est el documento con el enlace, y por tanto,
reemplaza a dicho documento. Si el navegador no sabe cmo presentar el recurso, tratar de invocar un programa que s lo
haga o permitir al usuario guardar el recurso en su sistema de archivos.
Los elementos a nunca deben anidarse. A modo de sugerencia trate de usar como contenido del enlace texto que es parte de
la narrativa original del documento, no un "click aqu".
3.3.1 Anclas
El elemento a tambin permite darle nombre a un punto especfico del documento, al cual se le puede hacer referencia
posteriormente con un URL. A este punto se le llama ancla (en ingls, anchor, de ah el nombre del elemento a). La
siguiente notacin crea un ancla en el documento
<a name="nombre_ancla" />
Para hacer referencia a un ancla, se crea un enlace y se le indica al navegador que su destino es el nombre del ancla pero
antecedido por un smbolo de nmero (#). De esta forma un enlace puede apuntar hacia un documento web, y con el
smbolo de nmero hacia una seccin especfica de dicho documento, como se ve en los siguientes ejemplos.
<!-- Apunta hacia un ancla en este mismo documento -->
<a href="#Introduccion">Introduccin</a>
<!-- Apunta hacia un ancla en otro documento -->
<a href="glosario.html#dtd">DTD</a>
Sin embargo, la practicidad de las anclas ha cado desde que el W3C permiti que cualquier elemento pueda ser identificado
de forma nica en el documento con el atributo id, al cual se le puede enlazar utilizando el mismo smbolo de nmero (#),
como se ve en el siguiente ejemplo.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<h1>Tabla de contenidos</h1>
<p>
<a href="#introduccion">Introduccin</a><br />
<a href="#arq_web">Arquitectura web</a><br />
</p>
<!-- ... -->
<h1 id="Introduccion">Introduccin</h1>
<!-- ... -->
<h1 id="arq_web">Arquitectura web</h1>
Aunque el atributo target est disponible en todas las variantes de (X)HTML, es prohibido su uso directo en XHTML-Strict,
debido a que especifica comportamiento y eso es responsabilidad de JavaScript. Ante esta restriccin se puede usar el
atributo rel que indica la relacin semntica entre el documento web y el recurso enlazado, y con JavaScript asignar el
atributo target manualmente una vez que el documento se haya cargado. Esto se estudiar luego.
22/09/2015 11:52 a. m.
31 de 99
Desdichadamente el comportamiento de los atajos del teclado son dependientes del navegador, y en algunos pueden no
funcionar o reemplazar otras operaciones preestablecidas del navegador.
La mayora de navegadores permiten recorrer los enlaces, controles de formularios y otros elementos con la tecla tabulador.
El autor puede alterar este orden con el atributo tabindex="n", donde n es la posicin en el orden que se quiere para ese
enlace o elemento. Si se le da un nmero negativo se sacar de la secuencia. Si dos elementos tienen el mismo valor para
este atributo, el navegador seguir el orden de aparicin en el documento.
3.4 Imgenes
La caracterstica ms notable del hipertexto es el soporte de varios medios, entre los que se incluyen las imgenes, las
cuales se almacenan en recursos (archivos) separados al documento web y se referencian desde ste. Para incluir una
imagen se utiliza el elemento vaco img, cuyo atributo src debe tener el URL que identifica el archivo con la imagen, y
puede ser absoluto o relativo al documento. La sintaxis ms bsica del elemento img es como sigue.
<img src="imagen.url" alt="descripcin de la imagen" />
(X)HTML requiere un texto alternativo que ser desplegado cuando la imagen no es cargada por alguna razn, como imagen
inexistente o porque el usuario ha deshabilitado las imgenes en su navegador. Algunos navegadores muestran este texto
como un "tooltip" cuando el puntero del ratn pasa sobre ellas, pero esa funcin es realmente responsabilidad del atributo
title, el mismo que se usa en los elementos de frase estudiados en la seccin de texto estructurado. Si la imagen se va a
usar como una decoracin y no se quieren "tooltips", asigne un valor vaco en estos atributos, de la forma <img alt=""
title="" ... />. La apariencia del texto alternativo se puede ajustar con hojas de estilo.
Si el valor indicado en los atributos ancho o alto de img no coincide con el tamao real de la imagen, el navegador la
escalar. Tambin se puede especificar en ellos un porcentaje de la ventana, algo como width="75%". Normalmente las
aplicaciones de diseo web se encargan de asignar los valores reales de la imagen en forma automtica. El ancho y alto de
una o varias imgenes y otros detalles se pueden controlar con estilos, lo cual es muy til para un conjunto grande de
imgenes que comparten las mismas dimensiones.
Tipo
Colores
Transparencia Prdida
Utilidad
PNG
Escalar
256 / 16M S
No
Ilustraciones
JPEG
Escalar
16M
No
Fotografas
GIF
Escalar
256
No
Animaciones sencillas
SVG
Vectorial 16M
S
No
Ilustraciones
Formatos de imagen soportados por navegadores
Cuando un autor quiere representar alguna pieza de informacin en forma grfica, debe decidir si utilizar una fotografa,
una ilustracin o una animacin. Esta decisin ayuda en gran medida a delimitar el formato a escoger.
22/09/2015 11:52 a. m.
32 de 99
Una fotografa tiene millones de colores o grises. Se obtienen por cmaras digitales o escneres. Ambos dispositivos no
proveen informacin de transparencia. El formato ms recomendable para fotografas es el JPEG, creado en 1992 por el
Joint Photographic Experts Group. Es un algoritmo de prdida de calidad que trata de descartar detalles que el ojo humano
no percibe con el fin de ahorrar espacio. El formato PNG (Portable Network Graphics) tambin puede almacenar fotografas,
pero sin prdida de calidad, lo cual es poco recomendable para el web ya que su tamao compromete la velocidad de carga
del documento.
Una ilustracin es una imagen, normalmente en dos dimensiones, que contiene texto o lo complementa. Suelen contener
diagramas o dibujos hechos en un programa de cmputo, en contraposicin a una cmara o escner. La cantidad de colores
de una ilustracin suele se reducida. El formato PNG o SVG (Scalar Vector Graphics) son aptos para ilustraciones, la
diferencia entre ambos es el tipo de imagen: escalar o vectorial respectivamente.
Una imagen escalar es un mapa de bits, es decir, una matriz de tamao definido donde cada celda o pixel almacena un
color codificado en forma numrica. "Redimensionar" a menor tamao una imagen escalar provoca que sta se deforme en
especial si no se mantiene su proporcin. Si se agranda una imagen escalar provocar que los pixeles se propaguen a las
celdas adyacentes, generando zonas de colores poco agradables a la vista humana.
Una imagen vectorial est compuesta por figuras geomtricas como puntos, lneas, curvas o polgonos. Sus atributos como
posicin y tamao son los que se almacenan en el archivo. "Redimensionar" una imagen vectorial a cualquier tamao
significa reajustar las posiciones de las figuras geomtricas y volverlas a pintar, lo que provoca que la imagen siempre se
vea agradable a la vista humana.
La explicacin anterior facilita la decisin hacia SVG como formato de eleccin para ilustraciones, sin embargo hay que
tener en cuenta que, aunque SVG es un estndar abrigado por el W3C, su implementacin en los navegadores actuales es
parcial y quiz ausente en aquellos de dispositivos mviles, debido a que su despliegue requiere de mayor poder de cmputo
que un PNG. Algunos sitios web como Wikipedia usan SVG, pero si el navegador no soporta este formato, el servidor web
enva a cambio un PNG autogenerado.
Si el autor encuentra que una animacin es el mejor medio de comunicar algo, puede usar una imagen GIF (Graphics
Interchange Format), que permite animaciones escalares muy sencillas y limitadas a 256 colores. Si se requiere
animaciones vectoriales, el autor podra considerar HTML5 o Adobe Flash. Si se requiere animaciones de ms de 256
colores, se trata de un video y estos pueden incrustarse con objetos como se estudiar en la seccin Objetos multimedia.
Indiferentemente de si se utilizan imgenes escalares o vectoriales, el autor debe conseguir reducir el tamao tanto como
se pueda sin que la imagen se vea desagradable al lector. El autor necesita que el editor de imgenes lo apoye en esta labor.
Normalmente estos programas proveen una opcin que permite variar el tamao en bytes de la imagen u otros parmetros
y ver el efecto en tiempo real en la visualizacin de la misma. Es importante que el autor guarde adems la imagen original
en un formato con mayor calidad o sin prdida alguna.
Existe considerable cantidad de editores de imgenes disponibles, desde los renombrados paquetes de Adobe: Photoshop
para imgenes escalares e Illustrator para imgenes vectoriales. Como opciones libres a estos programas se puede citar
Gimp e Inkscape respectivamente.
Vase http://en.wikipedia.org/wiki/Favicon para otros tipos de imgenes y enlaces a usar como favicons
3.5 Tablas
(X)HTML permite organizar datos en forma tabular con el elemento table. Una tabla consta de filas declaradas con el
elemento tr (table record). Cada fila se compone de celdas td (table data). El siguiente ejemplo muestra una tabla sencilla.
Una tabla consta de tres partes: un encabezado de tabla opcional, el cuerpo de la tabla y el pie de tabla opcional. Cada una
de esas partes consta de filas.
22/09/2015 11:52 a. m.
33 de 99
3.6 Formularios
22/09/2015 11:52 a. m.
34 de 99
22/09/2015 11:52 a. m.
35 de 99
selector { declaration }
El selector determina cules elementos sern afectados por los estilos definidos en la declaracin, y puede ser uno o varios
elementos separados por comas. La declaracin es una lista de parejas propiedad: valor que sern aplicadas a los
elementos listados en el selector. Dichas parejas se separan por el smbolo punto y coma (;). Es opcional terminar en punto
y coma la ltima pareja. Con esto la sintaxis se expande a:
element1, element2, ..., elementN
{
property1: value1;
property2: value2;
...
propertyN: valueN;
}
Es muy conveniente que escriba comentarios explicando la intencin de cada regla, o al menos de aquellas no triviales. Los
comentarios utilizan la misma notacin del lenguaje de programacin C:
/* Las definiciones deben estar en negritas y no en itlicas como ocurre en ciertos
navegadores. Globalmente se usa verde para definiciones y ttulos; azul para enlaces. */
dfn
{
font-weight: bold;
font-style: normal;
color: #004444;
}
El atributo media del elemento link indica si las reglas de estilo aplican a un medio especfico, como la pantalla (screen), la
impresora (print), programas de lectura sintetizada (aural), computadoras de mano (handheld), televisores (tv) y otros. En
el ejemplo anterior, un navegador cargar la hoja styles1.css y los aplicar al documento web para ser visualizado en la
pantalla. Si el usuario decide imprimir el documento, el navegador cargar styles2.css y los aplicar en la copia que
enviar a la impresora. El atributo media es opcional, y si no se especifica en un elemento, se asume que esa hoja de estilos
aplicar a todos los medios, lo que equivale a darle el valor media="all". El atributo media puede contener varios valores
separados por comas, de esta forma, una hoja de estilos puede aplicarse a varios medios simultneamente.
El segundo lugar donde se pueden escribir reglas de estilo es en uno o varios elementos style dentro del encabezado (head)
del documento (X)HTML, como se aprecia en las lneas 6 a 8 del listado prettyprint linenums lang-html 4.1. Ntese que el
encabezado head admite combinar hojas de estilo externas y elementos style en cualquier orden. La especificacin CSS
22/09/2015 11:52 a. m.
36 de 99
indica que el navegador debe respetar este orden, de tal forma que las reglas de estilo que se encuentran en un archivo
.css, tienen el mismo efecto que si se escribiesen directamente en un elemento style del encabezado.
El tercer lugar donde se puede especificar reglas de estilo es en el atributo style del elemento mismo, como se hizo en la
lnea 12 del listado prettyprint linenums lang-html 4.1. En este caso, todas las propiedades aplicarn nicamente a dicho
elemento por lo que no es necesario especificar un selector, ni agrupar las propiedades dentro de llaves { }.
<html>
<head>
<title>Estilos en conflicto: cascada</title>
<link rel="stylesheet" type="text/css" href="cascading1.css"/>
<style type="text/css">
p { color: teal; }
</style>
</head>
<body>
<p>Este es el primer prrafo. Ninguna regla de estilo para <code>p</code>
especifica la fuente, por lo que <em>hereda</em> la fuente de su elemento padre
<code>body</code>. Aunque hay una hoja de estilos externa que especifica que el color
del texto de los prrafos debe ser rojo, ste es <strong>verde azulado</strong>
porque hay una regla en el encabezado del documento, que est ms cerca de este
prrafo.</p>
<p style="color: green;">Este es el segundo prrafo. Tiene un atributo de estilo que
sobrescribe el color del texto a <strong>verde</strong>, ya que por
<em>especificidad</em> est ms cerca del elemento. Ninguna regla de estilo formatea
la separacin vertical entre prrafos, por lo que se aplica la que el navegador tenga
implementada internamente.</p>
</body>
</html>
22/09/2015 11:52 a. m.
37 de 99
con serifas, como Times New Roman. Al cargar la hoja de estilos el navegador procesa la regla que indica que la fuente del
cuerpo (body) del documento debe mostrarse en Verdana, que es por el contrario una fuente sin serifas (sans-serif);
cualquier regla del autor tiene ms prioridad que el valor por defecto del navegador y por ende el navegador debe usar
Verdana para formatear el texto del body, el cual es vaco.
Al desplegar el primer prrafo, el navegador no encuentra una regla de fuente para dicho elemento de prrafo. Como es una
propiedad heredable, el navegador toma la fuente del padre del prrafo que es el elemento body, y por ende despliega el
texto del prrafo en Verdana. Esto mismo ocurre recursivamente para los elementos hijos del prrafo, como em, strong y
code; y luego para el prrafo siguiente. De esta forma, todo el documento aparece en Verdana como el autor podra esperar.
La propiedad de margen (margin) no es heredable de acuerdo a la especificacin CSS. El navegador web asume un margen
nulo o minsculo para el body, por lo que el texto se suele pegar con los extremos de la ventana del navegador. Al encontrar
la regla margin: 2.5cm, el navegador la aplica al elemento body, haciendo que el margen del documento sea de 2.5
centmetros. Sin embargo, al no ser una propiedad heredable, el navegador no aplica un margen de 2.5 centmetros a los
prrafos ni a los elementos em, strong y code, sino que asume el margen por defecto, que es de unos cuantos pixeles para
prrafos y de 0 pixeles para los otros elementos citados.
El color es una propiedad heredable segn la especificacin CSS. El navegador no encuentra una regla para el color de body
y asume el por defecto del navegador, que es negro. La regla p { color: red; } en la hoja de estilos cascading1.css, indica
al navegador que pinte todos los prrafos en rojo. Pero en la lnea 6 del documento web del listado prettyprint linenums
lang-html 4.2 compite por la misma propiedad: establecer el color de los prrafos en verde azulado (teal). Estas dos reglas
estn en conflicto, y ganar la que tenga mayor especificidad en el selector, sin embargo ambas tienen el mismo selector; y
en tal caso el navegador deber aplicar la que aparezca de ltimo de acuerdo al principio de ubicacin, y por ende, los
parrafos aparecern en verde azulado.
Al pintar el segundo prrafo que inicia en la lnea 18 del listado prettyprint linenums lang-html 4.2, el navegador encuentra
una regla para la propiedad color en su atributo style. De acuerdo al principio de especificidad esta regla tiene la mayor
prioridad y por ende, el segundo prrafo aparecer en verde simple en lugar de verde azulado.
4.1.3 El operador @
4.2 Selectores
inherit
Descripcin
Dele el valor inherit a una propiedad cuando usted
explcitamente quiere especificar que esa propiedad tome el
mismo valor que la del elemento padre.
Son magnitudes compuestas siempre de un valor y una unidad,
como 2.5cm las cuales no deben estar separadas por espacios. La
unidad se puede omitir slo cuando la magnitud es 0. Hay dos
tipos de unidades:
<length>
Ejemplos
p { margin: inherit; }
margin-top: 2em;
margin-bottom: 0;
}
<color>
div.content { z-index: 2; }
URL hacia otro recurso, como una imagen, sonido, etc. Si el URL
es relativo, lo ser con respecto a la hoja de estilos y no al
documento (X)HTML. Encerrar el URL entre comillas es opcional.
No separe la palabra url del parntesis que abre.
body
{
background: url(water.png) repeat;
}
22/09/2015 11:52 a. m.
38 de 99
Dominio
Descripcin
Notacin #. Se especifica las cantidades de rojo, verde y
azul en notacin hexadecimal antecedidos por un smbolo
de nmero, de la forma #rrggbb, o #rgb si los dgitos de
cada componente se repiten. Las letras hexadecimales
pueden estar en maysculas o minsculas o ambas.
Ejemplos
4.4 Propiedades
4.4.1 El modelo de fuente
5.1 Generalidades
JavaScript es un lenguaje similar a C/C++/Java. Es sensitivo a maysculas y minsculas, por lo que resulta ms consistente
con XHTML que con HTML. Aunque no es obligatorio, cada sentencia en JavaScript debe terminar en punto y coma, y se
considera una mala prctica omitirlos. Los comentarios utilizan la notacin de C++:
// comentario hasta el final de lnea
/* comentario que puede
extenderse varias lneas */
El cdigo JavaScript puede aparecer en cuatro lugares: en el elemento script, en un archivo .js externo, en un evento
intrnseco, y con el pseudoprotocolo javascript:.
22/09/2015 11:52 a. m.
39 de 99
1. <body>
2.
<h1>Cuadrados naturales 1</h1>
3.
<script type="text/javascript">
4.
<!-5.
document.write('<ul>\n');
6.
for ( var n = 1; n <= 20; ++n )
7.
document.write('<li>' + n + '<sup>2</sup> = ' + (n * n) + '</li>\n');
8.
document.write('</ul>\n');
9.
-->
10.
</script>
11. </body>
El cdigo JavaScript puede estar en un recurso externo y ser importado con el atributo src del elemento script. Correr este
ejemplo.
document.write('<ul>\n');
for ( var n = 1; n <= 20; ++n )
document.write('<li>' + n + '<sup>2</sup> = ' + (n * n) + '</li>\n');
document.write('</ul>\n');
22/09/2015 11:52 a. m.
40 de 99
El autor puede proveer cdigo JavaScript se que ejecuta cuando un evento ha ocurrido, como presionar un botn en este
caso. Correr este ejemplo.
5.2.1 Nmeros
JavaScript no hace diferencia entre nmeros enteros y de punto flotante. Todos son representados internamente como
punto flotante de 64bits (IEEE 754). Las constantes numricas de JavaScript siguen las mismas convenciones de C, excepto
los nmeros octales que no son parte de ECMAScript.
Cuando un valor flotante llega a ser ms grande que el ms grande de los representables, se almacena con el valor especial
Infinity o su opuesto negativo. Cuando se hace una operacin indefinida, se genera un nmero especial NaN (not-anumber), el cual nunca es igual a nada, incluso ni a l mismo, por eso debe usarse la funcin especial isNaN(). Otra funcin
prctica es isFinite(), que prueba si un nmero no es Infinite y no es NaN. A continuacin una lista de constantes
numricas especiales:
Infinity. Valor especial usado en lugar de un nmero gigante que no cabe en un double de 64 bits, por ejemplo el
resultado de la expresin 17/0.
NaN. Acrnimo de "not-a-number". Es un valor especial usado cuando una expresin no genera un nmero vlido,
como la divisin 0/0 o tratar de convertir un string no apto a un nmero como parseInt("cinco").
Number.MAX_VALUE. El nmero ms grande representable en un double de 64 bits.
Number.MIN_VALUE. El nmero decimal ms pequeo (cercano a cero) representable en un double de 64 bits.
Number.NaN. Igual a NaN.
Number.POSITIVE_INFINITY. Igual a +Infinity.
Number.NEGATIVE_INFINITY. Igual a -Infinity.
22/09/2015 11:52 a. m.
41 de 99
A diferencia de otros lenguajes de programacin, Las cadenas literales tienen que ser escritas en una nica lnea, no pueden
romperse en dos o ms de ellas.
Igual que en C/C++, JavaScript emplea secuencias de escape iniciadas en backslash (\) para representar caracteres
especiales, tales como \n para el cambio de lnea, \r para el retorno de carro, \" para comillas dobles, \' para apstrofe o
comilla simple, \0 para el carcter nulo y \\ para la barra invertida (backslash).
No se debe utilizar el backslash frente a un cambio de lnea para tratar de continuar un string en varias lneas; JavaScript
probablemente lo ignorar. En JavaScript las cadenas de caracteres o strings son un tipo de datos atmico, no un arreglo de
caracteres. De hecho JavaScript no tiene el concepto de carcter (char) como s ocurre en otros lenguajes de programacin.
Un carcter se representa como un string de longitud 1. El mtodo str.charAt(i) permite obtener un string con el carcter
que est en la posicin i de str, donde el ndice i est basado en cero, es decir, 0 representa el primer carcter de la
cadena. El siguiente cdigo muestra varias operaciones con strings:
var
var
var
var
var
Aunque algunas implementaciones permiten el uso del operador [] para acceder a un carcter especfico del string, es
recomendable evitar su uso, ya que no forma parte del estndar ECMAScript.
// "465.66128730773926"
// "465.66128730773926"
hdd_gib.toString();
hdd_gib.toString(2);
hdd_gib.toString(16);
// "465.66128730773926"
// "111010001.1010100101001010001"
// "1d1.a94a2"
hdd_gib.toFixed(0);
hdd_gib.toFixed(2);
// "466"
// "465.66"
hdd_gib.toExponential(0);
hdd_gib.toExponential(3);
// "5e+2"
// "4.657e+2"
hdd_gib.toPrecision(4);
hdd_gib.toPrecision(7);
// "465.7"
// "465.6613"
22/09/2015 11:52 a. m.
42 de 99
Cuando un string se utiliza en un contexto donde se requiere un nmero, ser traducido automticamente por JavaScript,
por ejemplo:
var product = "21" * "2";
// product == 42.
Con la notacin anterior no se podr sumar un string a un nmero con el operador +, ya que ser interpretado como
concatenacin. El constructor Number(str) convierte el string str en un nmero, siempre que str tenga formato de nmero
en base 10 y no inicie con espacios en blanco. Las funciones parseInt(str,base) y parseFloat(str,base) asumen que str
est en base base (10, si se omite) y lo convierten en un nmero entero o real respectivamente. Ejemplos:
parseInt("3 blind mice");
parseFloat("3.14 meters");
parseInt("12.34");
parseInt("0xFF");
//
//
//
//
Returns
Returns
Returns
Returns
3
3.14
12
255
parseInt("11", 2);
parseInt("ff", 16);
parseInt("zz", 36);
parseInt("077", 8);
parseInt("077", 10);
//
//
//
//
//
Returns
Returns
Returns
Returns
Returns
3 (1*2 + 1)
255 (15*16 + 15)
1295 (35*36 + 35)
63 (7*8 + 7)
77 (7*10 + 7)
parseInt("eleven");
parseFloat("$72.47");
// Returns NaN
// Returns NaN
Si la cadena a convertir inicia con "0x" se interpreta que est en hexadecimal. Si inicia con 0 su resultado es indefinido, ya
que algunas implementaciones podra interpretar octal o decimal, por lo que es conveniente siempre especificar la base. Si
no se puede convertir a un nmero, estas funciones retornan NaN.
5.2.4 Booleanos
Los valores booleanos slo pueden contener los valores literales false o true. Cuando se usa un booleano en un contexto
numrico, se convierten automticamente a los valores 0 y 1. Si se usan en un contexto string, JavaScript los convierte
automticamente a "false" y "true" respectivamente. El recproco tambin es vlido. Los valores especiales NaN, null,
undefined y la cadena vaca ("") siempre se convierten a false; todos los dems a true (como Infinity). Para hacer
explcita la conversin, es recomendable emplear la funcin Boolean():
var x_as_boolean = Boolean(x);
5.2.5 Funciones
El programador puede declarar sus propias funciones con la palabra reservada function, el nombre opcional de la funcin,
los parmetros sin tipos entre parntesis ( ), y el cuerpo de la funcin entre llaves { }. Las funciones en JavaScript son un
tipo de datos ms, por ende, una funcin es un valor; as, las funciones se pueden almacenar en variables, miembros de
objetos, arreglos, y pasarse por parmetros en una forma ms natural que en C/C++. Cuando una funcin se asigna a un
objeto como un miembro, recibe el nombre especial de mtodo. En caso de asignarse a una variable, puede omitirse el
nombre de la funcin, lo que en JavaScript se llama funcin literal o funcin lambda en homenaje al lenguaje Lisp que
fue uno de los primeros en permitir funciones sin nombre:
// una funcin nombrada
function square1(x) { return x*x; }
// una funcin literal o "lambda"
var square2 = function(x) { return x*x; }
// una funcin construida a partir de strings
var square3 = new Function("x", "return x*x;");
// invoca la funcin a travs de la variable square2
square2(2.5);
Una tercera forma de definir una funcin es pasar sus argumentos y cuerpo como strings a la funcin constructora
Function(), lo cual es poco usado e incluso, menos eficiente. Cuando el valor de una variable es una funcin, se puede
invocar sta usando el operador () tras el nombre de la variable, como se hizo en el ejemplo anterior con square2.
5.2.6 Objetos
Un objeto es una coleccin de valores nombrados, que usualmente se les refiere como propiedades, campos o miembros del
objeto, y se les accede utilizando el operador punto. Por ejemplo:
22/09/2015 11:52 a. m.
43 de 99
image.width
image.height
document.myform.button
document.write("write es un mtodo: una propiedad cuyo tipo de datos es una funcin");
El operador punto permite acceder a las propiedades utilizando identificadores. Pero JavaScript permite tambin usar
cadenas de caracteres para acceder a las propiedades, con el operador corchetes []. Esta segunda notacin permite ver a los
objetos como arreglos asociativos. Ejemplos:
image["width"]
image["height"]
document["myform"]["button"]
document["write"]("write es un mtodo: una propiedad cuyo tipo de datos es una funcin");
Los objetos se crean llamando funciones constructoras con el operador new, despus de lo cual se usan como de costumbre.
Estos objetos son almacenados en memoria dinmica por el navegador, el cual incorpora un recolector de basura (garbage
collector), de tal forma que ahorra al programador la responsabilidad de liberar la memoria de cada objeto creado.
var now = new Date();
var pattern = new RegExp("\\sjava\\s", "i");
var point = new Object();
point.x = 2.3;
point.y = -1.2;
En el ejemplo anterior el objeto point se cre como un objeto vaco, y sus propiedades se fueron agregando luego con el
operador de asignacin. Existe una notacin para definir objetos literales, til para inicializaciones:
{ property1: value1; "property2": value2; ...; propertyN: valueN }
Las llaves {} en JavaScript indican la creacin de un objeto literal. Los nombres de las propiedades pueden declararse como
identificadores o como strings. Los valores de cada propiedad pueden ser de cualquier tipo de datos de JavaScript (booleano,
numrico, string, funcin, arreglo, u objeto), sea como valores literales o como resultado de una expresin aritmtica. As
los objetos se pueden anidar como es de esperar:
var point = { x:2.3, y:-1.2 };
var activo1 =
{
"tipo": "disco_duro",
"precio": 30000, // colones
'tamanno': 500 * Math.pow(10, 9) / Math.pow(2, 30) // GiB
};
var rectangle =
{
color : "#a4f0ca",
background:
{
color: "lightgray",
image: "img/bricks.png",
repeat: "repeat"
},
geometry:
{
topLeft: { x: 45, y: 10 },
extend: { width: 21.93, height: 38.34 }
}
};
Si un objeto se emplea en un contexto Boolean, se traduce a true si no es null. Si el contexto es string se llamar al metodo
toString() y si es numrico a valueOf().
22/09/2015 11:52 a. m.
44 de 99
5.2.7 Arreglos
En JavaScript un arreglo es una coleccin de datos enumerados. Se acceden con un ndice entero, basado en 0, escrito
entre corchetes tras el nombre del arreglo. El siguiente ejemplo obtiene el ancho en pixeles de la segunda imagen en el
documento:
document.images[1].width
Los arreglos pueden tener datos heterogneos. As un elemento del arreglo puede contener otro arreglo, pero no hay
arreglos multidimensionales. Los arreglos se crean con el constructor Array() y sus elementos se pueden agregar
simplemente asignndolos a sus ndices o bien, como parmetros del constructor Array(); pero si se pasa un nico entero a
este constructor, de la forma Array(N) se crear un arreglo con N elementos indefinidos. Ejemplos:
var a = new Array();
// Arreglo vaco, lo mismo que: var a = [];
a[0] = 1.2;
// Un elemento es insertado en la posicin 0
a[1] = "JavaScript";
a[2] = true;
a[4] = { x:1, y:3 };
// La posicin 3 tiene un elemento con el valor undefined
a[5] = function(x) { return x*x; }; // a[5](7) retornar 49
a[6] = new Array();
// Elemento a[6] almacena un arreglo vaco
a[6][0] = -Infinity;
// Inserta un elemento en el arreglo que est en a[6]
var b = new Array(1.2, "JavaScript", true, { x:1, y:3 }); // 4 elementos
var c = new Array(10); // Arrreglo de 10 elementos indefinidos
JavaScript permite crear arreglos literales, preferiblemente utilizados para inicializacin, y son una lista de valores
separados por comas dentro de corchetes, que se asignan secuencialmente empezando en 0. Los elementos tambin pueden
ser indefinidos lo cual se logra omitiendo el valor entre comas:
var b = [ 1.2, "JavaScript", true, { x:1, y:3 } ];
var matrix = [[1,2,3], [4,5,6], [7,8,9]];
// matrix[2][1] == 8
22/09/2015 11:52 a. m.
45 de 99
La propiedad length no proviene del string s, sino de un objeto temporal String inicializado con s, una copia, que despus de
usarse, se desecha. Este comportamiento tambin aplica para los datos primitivos de Number y Boolean.
// Los parametros de la funcion no tienen tipo de datos, reciben por valor o referencia
// de acuerdo a los datos enviados en la invocacion
function addto(total, value) { total += value; }
// Se invoca con dos numeros, al llamar a addto, total y value tendrn copias por valor
// as que la funcion no tendra el efecto que quiere conseguir, y por ende, t se mantendra
// intalterado con su valor 1
addto(t, n);
// La comparacion se hace por valor, es decir, se comparan byte a byte variables distintas
if ( t == n ) document.write('Los nmeros son copiados');
// Se evaluar como true
Cuando los datos se manipulan por referencia, se hace una copia de la direccin del objeto. Es decir, se copian, pasan por
parmetro y comparan direcciones que apuntan a lo mismo, de forma similar a los punteros C. Por ejemplo:
// Crea un objeto y su direccion la copia a hoy
var hoy = new Date();
// Copia la direccion de hoy a navidad, ambas variables refieren al mismo objeto
var navidad = hoy;
// Modifica al objeto apuntado, por ende, 'hoy' tambien referir al 25 de diciembre
navidad.setMonth(11);
navidad.setDate(25);
22/09/2015 11:52 a. m.
46 de 99
Los strings no caben en ninguna de esas dos categoras. Una vez creado un string, JavaScript no permite modificarlo, es
decir, son inmutables. Asi que no tiene importancia saber si se pasa por copia o por referencia. Puede pensarse lo segundo
por razones de eficiencia. Lo nico que se puede averiguar es si se comparan por valor o por referencia, de esta forma:
// Determining whether strings are compared by value or reference is easy.
// We compare two clearly distinct strings that happen to contain the same
// characters. If they are compared by value they will be equal, but if they
// are compared by reference, they will not be equal:
var s1 = "hello";
var s2 = "hell" + "o";
document.write(s1 == s2 ? "Strings compared by value" : "Strings compared by reference");
5.2.11 Variables
Una de las primeras diferencias con otros lenguajes como C es que las variables de JavaScript no tienen un tipo de datos,
por lo que es perfectamente vlido asignarles un valor de un tipo y luego otro de diferente naturaleza:
var i = 16;
i = "diecisis";
Antes de que usted pueda usar una variable, tiene que haberla declarado con la palabra reservada var, o JavaScript
declarar una implcitamente por usted. Lo cual puede traer efectos secundarios. En la declaracin se deben inicializar las
variables, sino JavaScript lo har con el valor undefined.
Si una variable se declara dos veces en secciones var distintas y la segunda declaracin tiene inicializacin acta como una
simple asignacin. Todas las variables declaradas en una seccin var son permanentes, es decir, no se pueden eliminar con
el operador delete. La primera seccin de la clusula for o for/in, permite tambin declarar variables.
for(var i = 0; i < 10; ++i) document.write(i, '\n');
for(var i in obj) document.write(i, '\n');
Cuando se trata de leer una variable que no existe, se genera un error y el navegador detiene la ejecucin del script. Si se
le trata de asignar algo a una variable inexistente, se crear una variable global implcita. Las variables globales son visibles
en cualquier lugar donde haya cdigo JavaScript.
Las variables locales son aquellas creadas en secciones var en los cuerpos de las funciones, incluyendo a los parmetros. Las
variables locales se superponen a las globales. A diferencia de C y Java, JavaScript no tiene diferente alcance (scope) en
cada bloque. Mejor dicho, los bloques de JavaScript lo definen las mismas funciones y no las parejas { }, as todas las
variables de una funcin comparten el mismo alcance, indiferentemente del nivel de anidamiento de llaves en que se
declaren las variables. En el siguiente ejemplo; las variables o, i, j, k comparten el mismo scope.
function test(obj)
{
var i = 0;
if (typeof obj == "object")
{
22/09/2015 11:52 a. m.
47 de 99
var j = 0;
for(var k=0; k < 10; ++k)
{
document.write(k);
}
document.write(k);
}
document.write(j);
Las variables locales ocultan las globales, y las locales tienen alcance (scope) de toda la funcin. Esto puede generar
resultados confusos o sorprendentes. Por ejemplo:
1.
2.
3.
4.
5.
6.
7.
8.
En la funcin anterior no se imprime "global" en el primer alert de la lnea 4, porque se est usando la variable str local de
la lnea 5, la cual no ha sido inicializada an. Este comportamiento equivale al siguiente cdigo:
1.
2.
3.
4.
5.
6.
7.
8.
9.
La moraleja es siempre declare sus variables juntas al inicio de una funcin JavaScript. Se puede distinguir dos tipos de
variables: undefined y unassigned. Una variable sera indefinida si nunca se ha declarado. Al tratar de leerla se generar un
error y el navegador detiene la ejecucin del script. Una variable es unassigned si est declarada pero no se le ha asignado
un valor an. Al tratar de leerla, se evaluar con el valor especial undefined (posiblemente mejor hubiera sido llamado
unassigned).
var x;
alert(u);
j = 3;
Cuando se inicia un intrprete de JavaScript, lo primero que hace antes de ejecutar el cdigo fuente, es crear el global
object, el cual se encarga de almacenar todas las variables globales que se declaren en el cdigo. Cuando usted declara una
variable global, realmente est declararando una propiedad del global object.
El intrprete de JavaScript tambin define convenientemente otras propiedades (variables y mtodos) en el global object
que son de uso comn, como Infinity, parseInt(), y Math. La palabra reservada this usada en un contexto global (fuera
del cuerpo de una funcin), referencia especficamente al global object. En el caso del navegador, el global object es adems
la ventana del navegador, y se cumple:
this == this.window == window
Si las variables globales son propiedades de un global object qu son las variables locales? Tambin son propiedades de un
objeto temporal llamado call object, el cual se construye en cada invocacin de una funcin, y mantiene juntos los
parmetros, variables declaradas en el cuerpo de la funcin y el cdigo de la misma. Este objeto es el que impide que las
variables locales sobrescriban las globales cuando tienen el mismo nombre. Dentro de una funcin, this hace referencia al
call object en lugar del global object.
5.3 Expresiones
5.3.1 Operadores
Los operadores aritmticos de resta (-), multiplicacin (*), divisin (/) y mdulo (%) slo trabajan con nmeros. Si se usan
con otro tipo de datos, JavaScript intentar convertirlos a nmeros invocndoles el mtodo valueOf(). Ya que todo nmero
en JavaScript es un flotante, la divisin siempre es real, es decir, no hay divisin entera como ocurre en otros lenguajes. El
operador + acta como operador de suma si sus operandos son numricos, y como el operador de concatenacin si al menos
uno de ellos es string.
JavaScript tiene dos operadores para determinar semejanza. El operador de igualdad (==) indica si dos valores son el
mismo incluso tras hacer conversiones de tipos. El operador de identidad (===) dice que dos valores son idnticos si son
22/09/2015 11:52 a. m.
48 de 99
iguales y tienen el mismo tipo de datos. Sus opuestos respectivos son el operador de desigualdad (!=) y de no identidad
(!==). Por ejemplo:
"0" == false
"0" === false
// produce true
// produce false
Los operadores de comparacin <,<=,>,>= actan como de costumbre si sus operandos son del mismo tipo, sino se
tratan de convertir a nmeros, y si esta conversin falla se generar NaN, que siempre se evala como false en expresiones
lgicas.
1 + 2
"1" + "2"
"1" + 2
11 < 3
"11" < "3"
"11" < 3
"one" < 3
//
//
//
//
//
//
//
Addition. Result is 3.
Concatenation. Result is "12".
Concatenation; 2 is converted to "2". Result is "12".
Numeric comparison. Result is false.
String comparison. Result is true.
Numeric comparison; "11" converted to 11. Result is false.
Numeric comparison; "one" converted to NaN. Result is false.
Los operadores lgicos son los mismos de C/C++/Java: &&, || y !. Pero guardan una diferencia. Los operandos se
convierten a Boolean temporalmente para hacer la evaluacin del operador, pero el resultado del operador no es Boolean,
sino del tipo de datos del operando izquierdo. A esto se le puede sacar ventaja. En el siguiente ejemplo, la variable max
adquirir el primer valor numrico que no sea null en lugar de un valor booleano.
// If max_width is defined, use that. Otherwise look for a value in
// the preferences object. If that is not defined use a hard-coded constant.
var max = max_width || preferences.max_width || 500;
El operador ternario ?: funciona igual que en C. Los operadores de bits (bitwise operators): and (&), or (|), xor (^), not
(~), shift left (<<), shift right con signo (>>) y shift right with zero fill (>>>), slo trabajan con enteros de 32 bits y su uso
es inusual en JavaScript.
El operador in recibe al lado izquierdo un string y al derecho un objeto o arreglo. Se evala como true si el string es el
nombre de una propiedad del objeto al lado derecho, incluso si es heredada. Ejemplos:
var
var
var
var
var
//
//
//
//
//
Define an
Evaluates
Evaluates
Evaluates
Inherited
object
to true
to true
to false; not a property of point
property from Object; evaluates to true
El operador instanceof espera al lado izquierdo un objeto y al lado derecho el nombre de una clase (realmente una funcin
constructora). Evala a true si el lado izquierdo (el objeto) es una instancia de la clase.
var d = new Date();
d instanceof Date;
d instanceof Object;
d instanceof Number;
//
//
//
//
Create a new
Evaluates to
Evaluates to
Evaluates to
//
//
//
//
Create an
Evaluates
Evaluates
Evaluates
El operador unario typeof genera un string con el nombre del tipo de datos de su argumento a la derecha, que puede o no
estar entre parntesis. Tpicos resultados son "number", "string", "boolean", "object" (incluye los arreglos y null),
"function" y "undefined" cuando el parmetro no ha sido declarado. Ejemplo:
typeof
typeof
typeof
typeof
typeof
typeof
typeof
typeof
undefined
false
(3 / 1.1)
'0'
{}
[]
null
function() {}
//
//
//
//
//
//
//
//
retorna
retorna
retorna
retorna
retorna
retorna
retorna
retorna
"undefined"
"boolean"
"number"
"string"
"object"
"object"
"object"
"function"
Ya que typeof retorna "object" para objetos de tanta naturaleza, su utilidad se reduce a saber si su operando es o no de un
22/09/2015 11:52 a. m.
49 de 99
tipo de datos primitivo. Para saber la clase de un objeto hay que recurrir a otras tcnicas como el operador instanceof, o la
propiedad Object.constructor, como se ver luego.
Igual que en C++ y Java, el operador new crea un objeto vaco, invoca un constructor para que lo inicialice, y retorna la
direccin de memoria del objeto. Si el constructor no recibe parmetros, puede omitirse sus parntesis.
o = new Object;
d = new Date();
El operador delete intenta eliminar una propiedad de un objeto, un elemento de un arreglo o la variable especificada como
operando. Retorna true si la eliminacin fue exitosa. Algunas variables o propiedades no pueden ser eliminadas, como las
declaradas en secciones var. Si el nico argumento de delete no existe, se retorna true. Ejemplos:
var o = {x:1, y:2};
delete o.x;
typeof o.x;
delete o.x;
delete o;
delete 1;
x = 1;
delete x;
x;
//
//
//
//
//
//
//
//
//
Ntese que delete no se trata de eliminar memoria dinmica como ocurre en C++, lo cual se hace en JavaScript con el
garbage collector, no hay otra forma. El delete de JavaScript elimina una propiedad, es decir, deja de existir; no es que se le
asigne undefined:
var my = new Object( );
my.hire = new Date( );
my.fire = my.hire;
delete my.hire;
document.write(my.fire);
//
//
//
//
//
5.3.2 Sentencias
Las sentencias en JavaScript deben terminar en punto y coma, aunque no es obligatorio. Las estructuras de control
condicional son las mismas de C: if, else y switch, como muestra el siguiente ejemplo.
if (username != null)
alert("Hello " + username + "\nWelcome to my blog.");
else if ( askname )
{
username = prompt("Welcome!\n What is your name?");
alert("Hello " + username);
}
else
alert("Hello there");
La estructura de control switch es ms flexible que en C. Al ser un lenguaje interpretado, los casos del switch son
expresiones, no slo constantes. El parmetro del switch se compara contra cada case utilizando el operador de identidad
===, hasta encontrar una coincidencia o el default si fue provisto por el programador.
function transfer(file, method)
{
switch(method)
{
case 'none':
break;
case 'ftp':
return transfer_ftp(file);
case 'rsync':
default:
return transfer_rsync(file);
}
}
Los ciclos for, while y do/while tienen la misma sintaxis de C. Por ejemplo:
// Llenar un arreglo con 20 factoriales: del 0 al 19
var factorials = new Array(20);
for(var i = 0; i < factorials.length; ++i)
factorials[i] = i ? i * factorials[i - 1] : 1;
// Imprimir el arreglo en el documento
22/09/2015 11:52 a. m.
50 de 99
JavaScript agrega un tipo de ciclo ms, el ciclo for/in, cuya sintaxis es:
for (property_name in object)
statement;
donde property_name se refiere al nombre de una variable, una declaracin var, un elemento de un arreglo, la propiedad de
un objeto, o incluso una expresin. object se refiere a un objeto o una expresin que evala en un objeto. El cuerpo del
for/in, se ejecuta una vez por cada propiedad del objeto y en cada iteracin, property_name adquiere el nombre la
propiedad, es decir, un string. Por ejemplo:
for (var prop_name in my_object)
document.write("name: " + prop_name + "; value: " + my_object[prop_name], "<br/>");
Ya que property_name puede ser una expresin arbitraria, cada vez que se itera se podra evaluar de forma diferente. Por
ejemplo, este cdigo copia los nombres de un objeto en un arreglo:
var obj = {x:1, y:2, z:3};
var arr = new Array( );
var i = 0;
for( arr[i++] in obj )
;
// Imprime cada nombre en el arreglo
for(i in arr) alert(i);
22/09/2015 11:52 a. m.
51 de 99
La propiedad constructor sirve para saber si un objeto es instancia directa de una psudoclase particular, mientras que el
operador instanceof sirve para determinar si el objeto es descendiente de una pseudoclase dada. Por ejemplo:
var d1 = new Date();
d1.constructor == Date
d1.constructor == Object
d1 instanceof Date
d1 instanceof Object
d1 instanceof Array
//
//
//
//
//
true
false
true
true, todo objeto es descendiente de Object
false
//
//
//
//
true
true
true
true
//
//
//
//
//
//
//
//
true
true
false
false
true
true
true
true
El mtodo toString() heredado de la pseudoclase Object es invocado automticamente por JavaScript cuando necesita
convertir el objeto en un string. La implementacin por defecto retorna la cadena "[object Object]" que es poco
significativa. Por ende, este mtodo debera ser sobrescrito por clases descendientes.
El mtodo valueOf() es invocado automticamente por JavaScript cuando el objeto se utiliza en un contexto numrico.
Tambin debera ser sobrescrito para clases descencientes.
Detalles
Mtodos de Array
22/09/2015 11:52 a. m.
52 de 99
Mtodo
push(elems)
Detalles
Inserta los elementos enviados por parmetro al final del arreglo. Retorna la cantidad de elementos que quedan en
el arreglo.
Elimina y retorna el ltimo elemento del arreglo. Si est vaco, retorna undefined.
unshift(elems) en el arreglo.
[1,2,3].unshift(9,null) // retorna 5, deja [9,null,1,2,3]
shift()
join(sep)
toString()
reverse()
sort(comp)
slice(i,j)
Como se ve en el ejemplo anterior, la invocacin de min() con tres parmetros falla el resultado esperado por el llamador. La
funcin min podra detectar esto con la propiedad length, heredada de Function, la cual indica la cantidad de parmetros
especificados en la declaracin de la funcin. Por ejemplo:
// Esta version de min solo trabaja con dos parametros
function min(a,b)
{
// Si el numero dado de argumentos es diferente del esperado, lance un error
if ( arguments.length != min.length )
throw new Error('min(): expected ' + min.length + ' arguments, sent ' + arguments.length);
// Solo dos parametros fueron provistos como se esperaba
return a < b ? a : b;
}
try
{
min();
min(3);
min(3, 0.07);
min(3, 0.07, -0.5);
//
//
//
//
Lanza excepcion
Lanza excepcion
Retorna 0.07
Lanza excepcion
}
catch(exc)
{
document.write(exc);
}
Una funcin que exige un nmero estricto de argumentos. Correr este ejemplo.
22/09/2015 11:52 a. m.
53 de 99
Sin embargo, en JavaScript es fcil escribir una funcin que trabaje con un nmero arbitrario de parmetros, como se ve a
continuacin.
function min()
{
var result = arguments.length ? Number.MAX_VALUE : undefined;
for (var i = 0; i < arguments.length; ++i)
if ( arguments[i] < result )
result = arguments[i];
return result;
}
min();
min(3);
min(3, 0.07, -0.5);
// retorna undefined
// retorna 3
// retorna -0.5
Una funcin que recibe un nmero arbitrario de argumentos. Correr este ejemplo.
Ya que una funcin es un objeto, puede tener propiedades, como la propiedad length que es creada por la pseudoclase
Function, y el arreglo arguments visto anteriormente. El programador tambin puede crear sus propias propiedades, las
cuales tendrn el efecto de ser "variables estticas" de la funcin. El siguiente ejemplo muestra una funcin que reporta el
nmero de veces que ha sido invocada.
// Crea una "variable esttica" como propiedad de la funcin. JavaScript "parsea" el cdigo
// antes de ejecutarlo, por lo que el nombre de la funcin puede usarse antes de ser declarada
countCalls.count = 0;
function countCalls()
{
// Usar la propiedad como si fuese una variable esttica
document.write('<p>countCalls() ha sido llamada ' + ++countCalls.count + ' veces</p>');
}
countCalls();
countCalls();
countCalls();
Simular una variable esttica dentro de una funcin. Correr este ejemplo.
5.5 Pseudoclases
JavaScript no tiene el concepto de clase como s C++ o Java, sino que las clases se simulan con funciones inicializadoras,
objetos y prototipos de objetos. Una funcin constructora o funcin inicializadora es una funcin cualquiera que recibe
un objeto por parmetro this y le crea propiedades y mtodos. Por ejemplo:
// Construye un rectngulo. Recibe un objeto en el parmetro oculto this
function Rectangle(w, h)
{
// Declara propiedades y las inicializa
this.width = w;
this.height = h;
// Tambin puede crear mtodos
this.area = function() { return this.width * this.height; }
}
Las funciones constructoras son invocadas con el operador new. Este operador hace lo siguiente. Crea un objeto vaco, sin
propiedades. Invoca a la funcin constructora pasndole el objeto vaco por parmetro para que lo incialice. Finalmente
retorna la direccin de memoria del nuevo objeto.
var rect1 = new Rectangle(2, 4);
// rect1 = { width:2, height:4 };
var rect2 = new Rectangle(8.5, 11); // rect2 = { width:8.5, height:11 };
document.write("Area of rect2: " + rect2.area() ); // Imprime "Area of rect2: 93.5"
Todos los objetos que sean inicializados con la funcin Rectangle() tendrn un width y un heigth, el desarrollador puede
utilizar con confianza estas propiedades. La funcin constructora no debe retornar un valor, ya que reemplazar el resultado
de la expresin new. Ntese que nunca hubo una clase, sino una funcin constructora y objetos tradicionales que son
inicializados con ella. Por esto se les llama pseudoclases y la funcin constructora es quien da nombre a la pseudoclase.
Como es de esperarse, todos los objetos inicializados con Rectangle() tienen su propia copia independiente de width y
height. Esto implica que en el ejemplo anterior, si a rect2.width se le asigna otro valor, no afectar al valor de rect1.width,
22/09/2015 11:52 a. m.
54 de 99
como el programador naturalmente espera. Sin embargo, esto mismo ocurre con los mtodos: cada objeto inicializado con la
funcin constructura Rectangle() tendr su propia copia independiente del mtodo area(), lo cual es ineficiente. Esta
redundancia se elimina con los objetos prototipo.
Todas las funciones que el programador defina, tendrn automticamente otra propiedad llamada prototype creada por
Function, de la misma forma que length y arguments. La propiedad prototype es un objeto, definido como una "variable
esttica" y por tanto, todas las invocaciones a la funcin tendrn acceso al mismo prototype.
Como la funciones constructoras son funciones normales, tambin tienen una propiedad prototype, y cada vez que se invoca
el operador new, ste implcitamente agrega una propiedad al nuevo objeto para que apunte al prototype de la funcin
constructora. El siguiente pseudocdigo explica lo que hace el operador new internamente:
// El programador define una funcin constructora
function Constructor(a,b) { this.prop1 = a; this.prop2 = b; }
// La pseudoclase Function inserta una propiedad length en la funcin implcitamente
Constructor.length = 2;
// La pseudoclase Function inserta una propiedad prototype en la funcin implcitamente
Constructor.prototype = {};
El lenguaje JavaScript especifica que cualquier propiedad asignada al objeto Constructor.prototype, ser automticamente
una propiedad compartida por todos los objetos construidos con la funcin Constructor, incluso, aunque dicha propiedad sea
asignada despus de que los objetos fueron creados. De esta forma, las propiedades creadas por la funcin constructora
directamente en el objeto sern copias independientes en cada objeto, y las propiedades creadas en el prototipo de la
misma, sern propiedades compartidas por todos los objetos (lo que en C++ y Java se conoce como miembros estticos).
Por ejemplo:
// Construye un rectngulo. Recibe un objeto en el parmetro oculto this
function Rectangle(w, h)
{
// Cada objeto tendr una copia independiente de estas propiedades
this.width = w;
this.height = h;
}
// Este mtodo ser compartido por todos los objetos creados con new Rectangle()
Rectangle.prototype.area = function() { return this.width * this.height; }
Ntese que el mtodo area() no se defini dentro de la funcin constructora. Si eso se hubiera hecho, se hara la asignacin
por cada rectngulo creado durante la ejecucin del programa, lo cual es ineficiente.
El prototype es el lugar ideal para definir mtodos, constantes y variables compartidas por todos los objetos de una misma
pseudoclase. El programador querr la mayor parte del tiempo tratar estas propiedades como de slo lectura. Si modifica
una propiedad en el prototipo directamente, el cambio afectar a todos los dems objetos inmediatamente; pero si intenta
modificar la propiedad a travs de un objeto cualquiera, crear una nueva propiedad en ese objeto que oculta la del
prototipo. Por ejemplo:
// El programador define una pseudoclase con una funcin constructora
function Circle(radius) { this.radius = radius; }
// Y un mtodo que ser compartido por todos los objetos creados con new Rectangle()
Circle.prototype.area = function() { return Math.PI * this.radius * this.radius; }
// circle1 y circle2 tienen su respectivo radius, son copias independientes
var circle1 = new Circle(7);
var circle2 = new Circle(2.5);
// circle1 y circle2 comparten el mismo mtodo area()
22/09/2015 11:52 a. m.
55 de 99
que han
Imprime
Imprime
Imprime
sobrescrito la propiedad
0
9.82
0
22/09/2015 11:52 a. m.
56 de 99
De lo anterior se obtiene que da lo mismo escribir window.document que simplemente document. Dicho de otra forma, el
objeto window es el ms importante porque todos los dems objetos que existen se acceden a atravs de l, como se ve en la
siguiente jerarqua parcial:
window
parent
top
navigator
location
history
screen
document
anchors[]
links[]
images[]
applets[]
forms[]
elements[]
La jerarqua que nace del objeto document ha sido estandarizada por el Consorcio Web (W3C) en lo que se llama Document
Object Model (DOM), de tal forma que permite a los programadores JavaScript escribir cdigo portable entre navegadores
para manipular el documento y sus estilos.
Como se indic al iniciar este captulo, el cdigo JavaScript puede correr en cuatro lugares: en un elemento script, en un
archivo .js externo, en atributos manejadores de eventos y en el pseudoprotocolo javascript:. Todos comparten el mismo
objeto global window y su descendencia; por ende, cualquier propiedad definida en uno de estos lugares, es accesible en
todos los dems. En el siguiente ejemplo, la funcin global genRandom() es definida en el primer script y usada en el segundo
script.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Global properties</title>
<script type="text/javascript">
// Global property, same as window.genRandom = function() {...}
function genRandom(maxValue)
22/09/2015 11:52 a. m.
57 de 99
{
return Math.floor(Math.random() * maxValue);
}
</script>
</head>
<body>
<p>Su nmero de la suerte es:
<script type="text/javascript">
// genRandom() is defined in another script. It can be called here
// because both scripts share the same global object: window
var num = genRandom(100);
// Same as window.num = window.genRandom(100);
document.write( num == 13 ? '(no juegue lotera esta semana)' : window.num );
</script>
.</p>
</body>
</html>
Variables globales son propiedades del objeto window. Correr este ejemplo.
5.6.1.1 El modelo de ejecucin de JavaScript
El cdigo almacenado en los elementos script se ejecuta slo una nica vez: cuando el documento (X)HTML es cargado en
el navegador. Una vez que se ha completado la carga, la interaccin se realiza mediante eventos. Cuando ocurre un evento,
normalmente generado por el usuario, el navegador puede invocar cdigo JavaScript del autor que reaccione al evento, el
cual se asocia al objeto que genere eventos a travs de atributos intrnsecos. En el siguiente ejemplo, cuando el usuario
hace click en la imagen se invoca el mtodo next() del objeto window.player, y mientras el mismo botn se mantiene
presionado, se invoca el mtodo forward del mismo objeto.
<img onclick="player.next();" onmousedown="player.forward();" src="img/button_next.svg">
El modelo de ejecucin de cdigo JavaScript sigue esta regla. El cdigo que aparece en los elementos script es ejecutado
en el mismo orden en que aparecen, durante la carga (parsing) el documento web. Cuando un elemento script termina de
ejecutarse, es reemplazado por su salida, la cual es el resultado de las posibles invocaciones a document.write() que se
hayan hecho. Inmediatamente el navegador contina analizando esta salida como cualquier otro cdigo (X)HTML, y
posteriormente el resto del documento web.
Una vez que el documento ha terminado de analizarse, todos los elementos script se habrn ejecutado y el contenido
externo, como imgenes o sonidos, habr sido cargado; el navegador dispara el primer evento: onload. El cdigo manejador
de este evento se escribe como valor del atributo onload del elemento body. El cdigo ejecutado en este punto, puede hacer
modificaciones libremente sobre la estructura del documento, ya que ste se encuentra totalmente cargado y analizado
(parsed); pero no debe invocar a document.write(), ya que har algo inesperado, como reemplazar el documento por
completo.
Despus de cargar el documento, correr los elementos script y atender el evento onload, el navegador entra en la fase de
manejo de eventos (event-driven phase), ejecutando el cdigo JavaScript que se haya asociado a los atributos intrnsecos
segn los vaya disparando el usuario. Estos manejadores de eventos tampoco deben invocar a document.write(), ya que
construirn un nuevo documento, remplazando el anterior.
Finalmente, cuando el usuario abandona la pgina, el browser dispara el evento onunload tambin de body, dando una
oportunidad final al cdigo JavaScript de correr. Este debe ser eficiente y silencioso, por ejemplo para hacer alguna limpieza
necesaria, evitando demoras que confundan al usuario. La siguiente tabla resume los eventos intrnsecos que el autor
dispone para mejorar la comunicacin con el lector.
Evento
Descripcin
onclick se dispara cuando el usuario hace click sobre el elemento. Si onclick retorna false, el browser no
onclick
onmousedown,
onmouseup
onmouseover,
onmouseout
onchange
onload
efecta la operacin por defecto asociada al elemento, por ejemplo, no seguir el hiperlink en caso de un enlace
(a), o no enviara un formulario en caso de un botn submit.
onmousedown es disparado cuando el usuario presiona el ratn sobre un elemento y onmouseup cuando suelta el
botn del ratn. Si ambos eventos ocurren sobre el mismo lugar de un elemento, se generar un onclick. La
mayora de elementos (X)HTML implementan estos dos eventos.
onmouseover se dispara mientras el cursor del ratn est sobre un elemento (X)HTML y onmouseout cuando
sale de l.
El manejador onchange se dispara en los elementos que permiten ingresar texto, como input, select y
textarea cuando el usuario cambia el valor desplegado del elemento y despus mueve el foco hacia otro
elemento.
El evento onload slo se puede asociar a body y es lanzado cuando el documento y su contenido externo,
incluyendo imgenes, han sido completamente cargados.
Eventos intrnsecos
Supngase que en una ventana del navegador el documento actual es reemplazado por otro, por ejemplo, cuando el usuario
escribe un nuevo URL. El nuevo documento no puede acceder a las propiedades que el documento previo cre en la
ventana, ya que el objeto window es reestablecido (reset) por el navegador. Esto implica que todas las funciones y
propiedades que los scripts definan, durarn mientras el documento actual se mantenga activo.
22/09/2015 11:52 a. m.
58 de 99
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Digital clock</title>
<style type="text/css">
body { background: black; margin: 4cm 0; text-align: center; }
#clock { font-size: 6em; color: #151520; text-shadow: 2px 2px 7px lightgray; }
</style>
</head>
<body>
<div id="clock">HH:MM:SS</div>
<script type="text/javascript">
window.setInterval( 'updateClock()', 1000 );
function updateClock()
{
var date = new Date();
document.getElementById('clock').innerHTML = date.toLocaleTimeString();
}
</script>
</body>
</html>
22/09/2015 11:52 a. m.
59 de 99
El siguiente ejemplo muestra un texto moverse de izquierda a derecha, en un ancho de 320 pixeles. Esta vez no se modifica
el contenido de un elemento particular, sino su posicin, lo cual es responsabilidad de la presentacin, por lo que el cdigo
JavaScript debe modificar el estilo CSS del elemento con identificador text dinmicamente. El estilo de un elemento se
accede en JavaScript a travs de su propiedad style, la cual es un objeto cuyas propiedades tienen el mismo nombre que
las propiedades CSS en notacin "camelCase" (margin, marginTop, etc.), y sus valores son siempre un string -esto se
estudiar con ms detalle luego-. En este ejemplo, cada vez que se invoca, animateText() calcula en la variable global
textLeft la nueva posicin del texto (lneas 18 y 19); y en la lnea 21 asigna el resultado de este clculo a la propiedad
style.left, cuyo efecto es el mismo a haber escrito #text { left: textLeft; } en CSS. Para que esto funcione, el
elemento #text debe "flotar" sobre el documento, lo cual se hizo en la lnea 6 indicando que su posicin es absoluta.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Texto animado</title>
<style type="text/css">
body { margin: 0; background: #ccc; color: #C8C8C8; font-size: 3em; }
#text { position: absolute; top: 2em; text-shadow: 1px 1px white, -1px -1px #444; }
</style>
</head>
<body>
<div id="text">Su nombre aqu</div>
<script type="text/javascript">
<!-window.setInterval( 'animateText()', 50 );
var textLeft = 0;
function animateText()
{
textLeft += 5;
if ( textLeft > 320 ) textLeft = -320;
var element = document.getElementById('text');
element.style.left = Math.abs(textLeft) + 'px';
}
-->
</script>
</body>
Un texto animado con JavaScript para desplazarse en vaivn de izquierda a derecha. Correr este ejemplo.
Descripcin
window.outerWidth,
window.outerHeight
window.screenX,
window.screenY
window.innerWidth,
window.innerHeight
Tamao del rea donde el documento se despliega (tambin llamada rea cliente o viewport.
Equivale al tamao de la ventana del navegador sin las barras de men, herramientas, scrollbars,
etc.
window.pageXOffset,
window.pageYOffset
El objeto window.screen provee informacin sobre la pantalla del usuario, por ejemplo: las dimensiones en pixeles del
escritorio (screen.width y screen.height), la profundidad de color en bits por pxel (screen.pixelDepth), el rea usable del
escritorio sin incluir la barra de tareas (screen.availWidth y screen.availHeight). Con estas propiedades el programador
puede escoger qu imgenes presentar, centrar una venana en el escritorio o tareas similares.
El objeto window.navigator contiene informacin sobre el navegador mismo, como su nombre (navigator.appName), versin
(navigator.appVersion), el nombre codificado (navigator.appCodeName, el sistema operativo para el que se compil el
22/09/2015 11:52 a. m.
60 de 99
//
//
//
//
//
Ntese que tanto document como window tinen mtodos open() y close(). El document.open(url) carga un documento a partir
del url o genera uno vaco si se omite url. Invocar a document.write() es seguro en una ventana nueva ya que el
documento se est cargando (parsing). El mtodo document.close() indica al navegador que el documento ha terminado de
cargarse (parsing), el cual responde deteniendo la animacin de carga. Sino nunca se llama a document.close(), el
navegador creer que est ante un documento incompleto.
El objeto window tiene mtodos para mover y redimensionar la ventana, lo cual es una pobre prctica, ya que esto debe ser
un privilegio del usuario. Son los siguientes: window.moveTo(x, y) mueve la esquina superior izquierda a las coordenadas
dadas; window.moveBy(despX, despY) mueve la ventana tantos pixeles relativos a la posicin actual;
window.resizeTo(width,height) y window.resizeBy(addToWidth, addToHeight) cambian el tamao de la ventana.
22/09/2015 11:52 a. m.
61 de 99
El mtodo window.focus() hace que la ventana sea la activa, y window.blur() hace que renuncie a serlo. Es comn llamar a
focus() despus de hacer un window.open(), ya que las ventanas recin creadas no lo tienen por defecto.
Es comn querer abrir un documento existente en una nueva ventana y luego hacer que sta se desplace a diferentes
fragmentos del documento dinmicamente. Si los fragmentos estn identificados con el atributo id (como en <div
id="frag1">...</div>) o con anclas (<a name="frag2">...</a>), se puede cambiar la ubicacin del documento con un una de
las siguientes instrucciones:
var subwindow = window.open('help.html', 'help_window');
subwindow.location.hash = "#frag1";
// crea una entrada en el History de subwindow
subwindow.location.replace("#frag1"); // no crea una entrada en el History de subwindow
Descripcin
href
protocol, host,
pathname, search
reload()
replace(url)
Reemplaza el documento actual en la ventana por uno nuevo cuyo URL es dado por parmetro. No genera
una entrada en el historial de la ventana, de modo que el usuario no tiene forma de regresar al documento
previo.
Propiedades del objeto window.location
Al objeto mismo window.location se le puede asignar un string, de la forma window.location = url, que causa el mismo
efecto que llamar su mtodo window.location.replace(url), con la diferencia de que se agrega una entrada al historial de
navegacin de la ventana, de tal forma que el usuario puede retornar al documento previo.
5.6.2.5 Cuadros de dilogo
El objeto window provee tres mtodos para desplegar cuadros de dilogo. window.alert(msg) despliega un mensaje y espera
que el usuario lo acepte. window.confirm(msg) presenta un mensaje y solicita al usuario que decida si lo acepta o cancela, lo
cual se retorna como un boolean. window.prompt(msg, defaultValue) presenta el mensaje msg y espera que el usuario
ingrese un string el cual es retornado o null si cancela. Obligatoriamente.
Deben usarse con moderacin, o mejor an, nunca. La mayora de usuarios se sentir molesta al experimentarlos y
recuerde que ellos tienen el poder de cerrar el navegador. As que estos mtodos son de ligera utilidad para el programador
durante el proceso de desarrollo. Hace varios aos, el navegador reportaba errores de JavaScript utilizando dilogos, lo cual
era impertinente: le reclamaba al usuario errores que no eran de l. Los navegadores han cambiado a ocultar los errores y
el programador debe buscarlos en alguna bitcora o similar.
document.title
Descripcin
Accede al ttulo del documento que se encuentra en el encabezado del mismo.
document.referrer
Es un string con el URL del recurso a travs del cual el usuario lleg al documento actual.
document.domain
Indica el dominio al cual pertenece el documento, y es usado por la poltica del mismo origen (same
origin policy).
Propiedades del objeto window.document
22/09/2015 11:52 a. m.
62 de 99
Las propiedades anteriores permiten, por ejemplo, escribir un pie de pgina dinmico, como el siguiente:
document.writeln('<address>');
document.write('<strong><a href="', document.URL, '">', document.title,'</a></strong>');
document.writeln('. ltima actualizacin: ', document.lastModified, '.<br/>');
document.write('©', new Date().getFullYear());
document.write(' <strong><a href="http://', document.domain,'">Mi Sitio</a></strong>');
document.writeln('. Todos los derechos reservados.');
document.writeln('</address>');
Un pie de pgina dinmico con propiedades del objeto document. Correr este ejemplo.
5.6.3.1 El modelo de objetos del documento (DOM)
Cuando el navegador carga un documento (X)HTML crea un objeto JavaScript por cada elemento, comentario, o trozo de
texto que encuentra en el archivo. Estos objetos se asocian entre s en una jerarqua llamada modelo de objetos del
documento (DOM: Document Object Model), la cual es accesible y modificable a travs de JavaScript. Es decir, el DOM es
una representacin interna del documento utilizando objetos. Un cambio en el DOM se refleja de inmediato en el navegador,
lo que permite al autor ajustar el documento dinmicamente para mejorar la comunicacin con sus lectores. Es quiz la
funcionalidad ms importante que un autor busca de JavaScript.
Los objetos en la jerarqua del DOM reciben el nombre genrico de nodos, construidos con la pseudoclase Node. El nodo raz
es siempre el documento, el cual contiene nodos opcionales (declaracin XML, declaracin de tipo de documento,
comentarios) y el nodo del elemento html. Este ltimo tiene dos hijos: el nodo del encabezado (head) y el nodo del cuerpo
del documento (body). Los hijos del nodo body varan de acuerdo al documento. Por ejemplo, la siguiente ilustracin muestra
un documento sencillo y el rbol de nodos que el navegador genera a partir de l.
22/09/2015 11:52 a. m.
63 de 99
#document
(Document node)
Un documento simple
(Comment node)
html
(Element node)
head
(Element node)
Documento simple
(Text node)
body
(Element node)
rbol de nodos
(Text node)
Un
(Text node)
documento minimalista
(Text node)
para estudiar sus nodos.
(Text node)
Las relaciones jerrquicas entre nodos implican que un nodo puede tener cero o ms nodos hijos (child nodes), nodos
hermanos (siblings), un nodo padre (parent), nodos descendientes y nodos ancestros. Estas relaciones se implementan
como propiedades de la pseudoclase Node. Dado un nodo se puede acceder a los otros nodos con los que est relacionado.
Estas y otras propiedades se resumen en la siguiente tabla.
Propiedad
Descripcin
Node.childNodes[]
Un arreglo que contiene los hijos del nodo actual en el mismo orden en que fueron definidos en el
documento. Si el nodo actual no tiene hijos, este arreglo estar vaco.
Node.firstChild
Node.lastChild
Node.nextSibling
El nodo hermano que contina al actual o null si es el ltimo hijo del nodo padre (parentNode). Equivale
al nodo que sigue al actual en el arreglo parentNode.childNodes[].
Node.previousSibling
El nodo hermano que precede al actual o null si es el primer hijo del nodo padre (parentNode). Equivale
al nodo que precede al actual en el arreglo parentNode.childNodes[].
Node.parentNode
El nodo padre o contenedor del nodo actual. Es null en el caso del nodo raz, nodos que han sido
separados (removidos) del documento, o nodos creados libremente que an no han sido insertados en el
documento.
Node.nodeType
Un entero que indica el tipo de nodo, por ejemplo: elemento (1), texto (3), comentarios (8).
Node.nodeName
Un string con un posible nombre para el nodo. Si el nodo es un elemento se utiliza el nombre del elemento
("body", "div", "p", etc.). Para los dems tipos de nodos se utiliza un texto generado de concatenar el
smbolo de nmero con el tipo de nodo, por ejemplo "#text", "#comment", "#document", etc.
Propiedades de la pseudoclase Node del XML DOM
22/09/2015 11:52 a. m.
64 de 99
Propiedad
Node.nodeValue
Descripcin
Si el nodo es de texto ( nodeType == 3) o comentario (nodeType == 8), esta propiedad tendr un string
con dicho texto; de lo contrario el valor null.
Node.textContent
Node.ownerDocument
Una referencia hacia el documento que contiene este nodo. Sirve, por ejemplo, para saber si dos nodos son
parte del mismo documento.
El siguiente cdigo recorre recursivamente todos los nodos del documento e imprime algunas de las propiedades heredadas
de la pseudoclase Node. La cantidad de nodos est fuertemente influenciada por el espacio en blanco que se utilice para
indentar el marcado, ya que el parser lo interpretar como datos de carcter y los almacenar en nodos de texto. [Para este
ejemplo, la impresin con document.write() debe hacerse en un documento distinto, ya que si se hace sobre el mismo,
generar una recursin infinita].
function printNodes(node, doc)
{
printProperties(node, doc);
for ( var i = 0; i < node.childNodes.length; ++i )
printNodes( node.childNodes[i], doc );
}
function printProperties(node, doc)
{
var properties = ['firstChild', 'lastChild', 'previousSibling', 'nextSibling',
'nodeName', 'nodeType', 'nodeValue', 'textContent' ];
for ( var i = 0; i < properties.length; ++i )
doc.writeln(properties[i], ': ', node[properties[i]]);
}
Una funcin recursiva que recorre el rbol de nodos del documento e imprime propiedades heredadas de la pseudoclase
Node. Correr este ejemplo con indentacin, o sin espacios en blanco.
Adems de las propiedades para acceder a nodos relacionados, la pseudoclase Node provee mtodos para modificarlos:
Propiedad
Descripcin
Node.appendChild(newChild)
Node.insertBefore(newChild,
referenceChild)
Node.replaceChild(newChild,
oldChild)
Reemplaza oldChild con newChild. Si newChild ya es parte del documento, ser removido
de su posicin actual y reinsertado en la nueva posicin. oldChild es separado del
documento y el cambio se refleja en el navegador. El objeto oldChild no es eliminado de la
memoria, sino que sigue vigente y puede ser reinsertado en el documento posteriormente.
Node.removeChild(child)
Quita al nodo child del arreglo childNodes[] y del documento (el cambio se refleja
visualmente en el navegador). El objeto nodo child no es eliminado de la memoria, y puede
ser reinsertado en el documento posteriormente.
Node.cloneNode(recursively)
Retorna una copia del nodo al cual este mtodo es invocado. No clona los hijos y
descendientes del nodo a menos que se enve true en el parmetro recursively. El nodo
retornado no es parte del documento, por lo que debe ser insertado posteriormente si se
quiere que sea visible al lector.
Node.isEqualNode(other)
Retorna true si el nodo es idntico al enviado por parmetro, es decir, tienen los mismos
valores para sus propiedades de datos (como el nombre y tipo), y as recursivamente para
todos sus hijos.
Mtodos de la pseudoclase Node del XML DOM
Los mtodos anteriores permiten mover nodos existentes de un lugar a otro, o clonarlos. El siguiente ejemplo ordena los
nodos existentes de una lista alfabticamente.
<body>
<h1>Reubicar nodos en el documento</h1>
<ol id="sortable_list">
<!-- Note: comments and text nodes will be ignored -->
<li>Los</li>
<li>12</li>
<li>elementos</li>
<li>de</li>
<li>esta</li>
<li>lista</li>
<li>sern</li>
<li>ordenados</li>
<li>alfabticamente</li>
<li>sin contar</li>
<li>Maysculas</li>
<li><p>Incluyendo <strong>este prrafo</strong>.</p></li>
22/09/2015 11:52 a. m.
65 de 99
</ol>
<p><button id="sort_button" onclick="sort_list()">Ordenar</button></p>
<script type="text/javascript">
<!-function sort_list()
{
// Get the parent node whose children will be sorted
var list_element = document.getElementById('sortable_list');
// Do not sort list_element.childNodes[] in place to avoid flickering
// Get an array of the elements to be processed and work with this array
var elements = [];
// Fill the working array with only the desired nodes to be sorted
for ( var child = list_element.firstChild; child; child = child.nextSibling )
if ( child.nodeName.toLowerCase() == 'li' )
elements.push(child);
// Function used to sort the array
function sort_elements(nodeA, nodeB)
{
var textA = nodeA.textContent.toLowerCase();
var textB = nodeB.textContent.toLowerCase();
return textA < textB ? -1 : textA > textB ? 1 : 0;
}
// Sort the elements alphabetically
elements.sort(sort_elements);
// Now elements are sorted in the array, not in the document, reinsert them
// in the desired order. Note, each node will be dettached from its current
// position and reinserted in the desired position automatically
for ( var i = 0; i < elements.length; ++i )
list_element.appendChild( elements[i] );
}
-->
</script>
</body>
Cuando se debe crear un nuevo nodo en el documento, no se debe hacer con el operador new, sino utilizar los mtodos
document.createXxx(data) de la pseudoclase Document. Por ejemplo, document.createElement(tagName) crea un nodo
elemento con la etiqueta tagName; document.createTextNode(string) crea un nodo de texto con el string como contenido;
document.createComment(string) crea un comentario. Todos ellos crean un nuevo nodo el cual no est asociado al
documento. El programador debe insertarlo posteriormente en la jerarqua de nodos para que sea visible al lector, usando
alguno de los mtodos de la pseudoclase Node como appendChild(), insertBefore() o replaceChild(). El siguiente ejemplo
inserta nodos en una lista ordenada.
<body>
<h1>Crear e insertar nodos en el documento</h1>
<p><button onclick="create_node()">Agregar nodo</button></p>
<ol id="dynamic_list">
<li>Presione el botn para agregarle elementos a la lista</li>
</ol>
<script type="text/javascript">
var counter = 0;
function create_node()
{
var list_item = document.createElement('li');
var text_node = document.createTextNode('Elemento autogenerado ' + ++counter);
list_item.appendChild( text_node );
document.getElementById('dynamic_list').appendChild(list_item);
}
22/09/2015 11:52 a. m.
66 de 99
</script>
</body>
Los nodos pueden ser de distinta naturaleza: elementos, atributos, comentarios, texto, etc. La propiedad Node.nodeType
indica el tipo de un nodo particular; es un entero que puede tomar el valor de una de las siguientes constantes:
Valor
Constante
Node.ELEMENT_NODE
Element
Node.ATTRIBUTE_NODE
Attr
Node.TEXT_NODE
Text
Node.CDATA_SECTION_NODE
CharacterData
Node.ENTITY_REFERENCE_NODE
EntityReference
Node.ENTITY_NODE
Entity
Node.PROCESSING_INSTRUCTION_NODE --
Node.COMMENT_NODE
Comment
Node.DOCUMENT_NODE
Document
10
Node.DOCUMENT_TYPE_NODE
--
11
Node.DOCUMENT_FRAGMENT_NODE
DocumentFragment
12
Node.NOTATION_NODE
--
HTMLElement
El siguiente ejemplo muestra una funcin que recorre recursivamente todos los nodos del documento contando cuntos de
ellos son elementos:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Conteo de elementos</title>
<script type="text/javascript">
<!-function countElements(node)
{
var count = 0;
if ( node.nodeType == Node.ELEMENT_NODE )
++count;
for ( var i = 0; i < node.childNodes.length; ++i )
count += countElements(node.childNodes[i]);
return count;
}
function fillCount()
{
document.getElementById('count').innerHTML = countElements(document);
}
-->
</script>
</head>
<body onload="fillCount()">
<h1>Conteo de elementos</h1>
<p>El <em>nmero de elementos</em> presentes en este documento es:
<strong id="count"></strong></p>
</body>
</html>
Una funcin recursiva que recorre el rbol de nodos del documento y retorna cuntos de ellos son de tipo elemento. Correr
este ejemplo.
Por cada tipo de nodo hay una pseudoclase hija de Node, que aparece en la tercera columna de la tabla anterior. Por
ejemplo, cuando el navegador carga el documento y encuentra un comentario, construye un objeto de la pseudoclase
Comment, la cual es hija de Node, y cuando encuentra un prrafo crear un objeto Element que es tambin hijo de Node. Esta
jerarqua de pseudoclases se ilustra a continuacin.
22/09/2015 11:52 a. m.
67 de 99
XML DOM
Node
Document
Entity
Element
CharacterData
Text
Att
Comment
HTML DOM
HTMLDocument
HTMLElement
HTMLHeadElement
HTMLTitleElement
HTMLBodyElement
HTMLParagraphElement
Cada subclase agrega propiedades a la pseudoclase Node. Por ejemplo, la pseudoclase Element define las siguientes
propiedades tiles:
Propiedad
Descripcin
Element.tagName
String con el nombre del elemento, por ejemplo: "body", "p", etc.
Element.attributes[]
Element.getAttribute(name)
Retorna el valor del atributo name como un string, o null si el elemento no tiene este
atributo.
Element.setAttribute(name,
value)
Asigna el string value al atributo con nombre name del elemento. Si el atributo no existe, lo
crea.
Element.removeAttribute(name)
Elimina el atributo con nombre name del elemento. No produce ningn error si el atributo no
existe.
Element.getAttributeNode(name)
Retorna un objeto de tipo Attr que permite por ejemplo saber si el atributo fue definido o se
est usando su valor por defecto.
Element.id
Element.className
Element.children[]
Un arreglo que contiene nicamente los elementos hijos de este elemento, en lugar de todos
los nodos como ocurre con el arreglo childNodes heredado de Node. Quiz childElements
hubiese sido un nombre ms apropiado.
Element.childElementCount
Element.innerHTML
Un string que con el marcado HTML o XML que representa el contenido del elemento. Si se
asigna otro string, ser "parseado" por el navegador, el resultado reemplazar a los nodos
hijos del elemento, y el efecto ser inmediatamente visible en el documento.
Element.outerHTML
Un string que con el marcado HTML o XML que representa el elemento mismo ms su
contenido. Si se asigna otro string, ser "parseado" por el navegador, el resultado
reemplazar al elemento y sus nodos hijos. El efecto ser inmediatamente visible en el
documento.
Element.style
Un objeto CSSStyleDeclaration con los estilos definidos en el documento para este elemento.
Se puede modificar dinmicamente. No contiene los estilos computados.
Propiedades de Element en el XML DOM
El objeto Attr representa un atributo de un elemento particular, aunque casi nunca se utiliza, ya que el objeto Element tiene
propiedades y mtodos para manipular sus atributos. Quiz su propiedad ms til es Attr.specified que permite
determinar si el valor del atributo fue explcitamente escrito en el documento, sino se est tomando el valor por omisin.
Los navegadores realmente implementan dos modelos de objetos del documento (DOM), uno para XML y otro especializado
para HTML. Dado que JavaScript utiliza XML para transferir datos entre el servidor y el cliente, requiere poder manipular
estos documentos a travs de una jerarqua de objetos. El DOM que se ha presentado hasta el momento se llama XML
DOM, compuesto de objetos bastante genricos como lo es tambin XML.
Sin embargo, el navegador provee un conjunto de pseudoclases especializadas para HTML, que componen lo que se llama
HTML DOM y que heredan de las pseudoclases presentes en el XML DOM. Algunas de estas pseudoclases se presentan en
verde en la figura {ver arriba}. El principal distintivo del HTML DOM es que define la pseudoclase HTMLElement para todos los
elementos que slo tienen los atributos comunes (em, span, dt, etc.) y una pseudoclase HTMLXxxElement para cada elemento
Xxx que tiene atributos propios, como HTMLDocument, body (HTMLBodyElement), p (HTMLParagraphElement), ul
(HTMLUListElement), etc.
Las pseudoclases HTMLXxxElement definen propiedades homnimas a los atributos (X)HTML que son de lectura y escritura.
Por ejemplo HTMLImageElement define el string src que puede cambiarse dinmicamente con JavaScript. Los nombres son
homnimos a XHTML, en minsculas, excepto el atributo class="" que en JavaScript se renombra className debido a que
22/09/2015 11:52 a. m.
68 de 99
class es una palabra reservada. El tipo de datos de cada atributo es el adecuado, por ejemplo, HTMLImageElement.src es un
string, HTMLImageElement.width es un entero y HTMLBodyElement.onload es una funcin de JavaScript.
El autor puede utilizar estos atributos definidos por las pseudoclases HTMLXxxElement directamente con el operador punto o
el operador corchetes, si est seguro de que el objeto es del tipo xxx adecuado. Tambin puede emplear los mtodos
getAttribute(name) y setAttributeValue(name, value) heredados de Element en el XML DOM; que a diferencia de los
atributos de HTMLXxxElement, slo retornan y reciben valores string.
Descripcin
document.getElementById(id)
document.getElementsByTagName(tagName)
document.querySelectorAll(selector)
CSS tiene una notacin estndar para seleccionar elementos a los cuales
aplicarles reglas de estilo; por ejemplo, el selector ".ejemplo" recupera
todos los elementos que tienen el atributo class="ejemplo" y "#cap01
a[rel='external']" selecciona a todos los enlaces que tienen el atributo
<a rel="external"> y que son descendientes del elemento identificado con
id="cap01". En JavaScript el mtodo
document.querySelectorAll(selector) retorna un arreglo con todos los
elementos que satisfacen el selector enviado por parmetro.
document.querySelector(selector)
document.getElementByName(name)
Esto es una mala prctica, ya que el documento (X)HTML slo debe especificar contenido y no estilo o comportamiento. As
22/09/2015 11:52 a. m.
69 de 99
que la asignacin debera hacerse con JavaScript, lo cual es muy simple, por ejemplo:
document.body.onload = function() { fixExternalLinks(); insertIndex(); }
Aunque la asignacin anterior se hizo con JavaScript y no en el documento (X)HTML, el esquema anterior tiene varios
problemas. Supngase que la asignacin anterior se hizo por un archivo1.js que es parte de una biblioteca 1. Un
programador que estuviese creando una biblioteca 2 en JavaScript que es independiente de la anterior, probablemente
necesitar invocar una funcin suya cuando el documento (X)HTML se ha cargado. En nuestro ejemplo esto implicara tener
que agregar una tercera funcin al evento onload de body Cmo hacer para agregar esta tercera funcin y mantener las
otras funciones que pueda ya tener asociadas?. Es deseable disponer de algn mecamismo que diga simplemente "agregue
este manejador al evento onload" sin importar cuntos eventos tiene ya asociados. De esto se encarga el mtodo
addEventListener().
El mtodo element.addEventListener(event, function, phase) hace que la funcin function sea invocada cuando el
elemento element produce el evento event. El nombre del evento en el primer parmetro es un string sin el prefijo 'on', por
ejemplo "mousedown". El segundo parmetro es una funcin que debe recibir slo un parmetro: un objeto de tipo Event y
debe retornar nada. El tercer parmetro es un booleano, con true indica que el evento puede ser atendido por uno de sus
ancestros, mientras que con false se le da primero oportunidad al elemento antes de que a sus ancestros (el por defecto).
Esto se explicar ms adelante. El siguiente ejemplo muestra un archivo .js que al ser incluido por un documento (X)HTML,
invoca dos funciones cuando ste termina de cargarse.
<!-- onload_event_dom2.html -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Eventos del DOM 2</title>
<script src="onload_event_dom2.js"></script>
</head>
<body>
<h1>Manejo de eventos del DOM level 2</h1>
</body>
</html>
// onload_event_dom2.js
function showInfo()
{
window.alert('Esta funcin JavaScript fue llamada sin que el documento hiciere' +
' nada especial, mas que incluir este archivo .js');
}
function addInfo()
{
var text = 'Este prrafo es producto de un segundo manejador de eventos.';
var paragraph = document.createElement('p');
paragraph.appendChild( document.createTextNode(text) );
document.body.appendChild( paragraph );
}
window.addEventListener('load', showInfo, false);
window.addEventListener('load', addInfo, false);
Un archivo .js que al ser incluido por un documento, agrega dos manejadores de eventos. Correr este ejemplo.
El mtodo Element.addEventListener() es parte de lo que se conoce como DOM Level 2, el establece que cuando un evento
ocurre en un elemento, ste puede antenderlo o alguno de sus elementos padres, es decir, el evento se propaga por la
jerarqua de elementos y puede ser atendido llama en una de las siguientes tres fases:
Capturing phase. El evento recorre desde el documento hasta el elemento esperando ser atendido.
At target phase. El elemento que gener el evento tiene oportunidad de atenderlo.
Bubbling phase. el evento retorna desde el elemento hacia el documento.
El tercer parmetro del mtodo element.addEventListener() controla la fase en la que ser atendido del evento. Si es true
se atender en la fase de captura, si es false en la fase objetivo o fase de ascenso (bubbling).
Otra ventaja de usar addEventListener() en lugar de asignar manejadores de eventos directamente a los atributos
intrnsecos (DOM Level 0), es que una misma funcin puede menejar eventos generados en distintos lugares del
documento. Por ejemplo, si quiere hacer algo cuando el cursor del ratn pase sobre cualquier prrafo del documento, en el
DOM Level 0 tendra que recorrer todos los elementos p y asignarles la funcin manejadora; mientras que en el DOM Level
2, simplemente registra la funcin en el elemento document.body con addEventListener().
Tanto en DOM Level 0 como DOM Level 1, la funcin que se asigna al atributo intrnseco o que se pasa en el segundo
parmetro de element.addEventListener() se convierte en una propiedad del elemento al cual se hizo la asignacin o
invocacin. Es decir, esa funcin se convierte en un mtodo del elemento. Cuando ste se invoca por el navegador, se har
como una invocacin a un mtodo normal del elemento, as la palabra reservada this har referencia a dicho elemento, por
lo que se puede usar dentro del cdigo del manejador. El siguiente ejemplo muestra una mnima implementacin de un
juego de estallar una bolsa de burbujas. Ntese cmo la funcin popBubble es asignada a cada imagen de burbuja al evento
onclick, lo que la convierte en un mtodo, el cual utiliza el parmetro this para cambiar el origen de la imagen presionada
por una burbuja estallada.
22/09/2015 11:52 a. m.
70 de 99
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Estallar burbujas</title>
<style type="text/css">
body { margin: 2cm; }
#wrap { width: 600px; height: 216px; margin: 0 auto; border: 5px solid #64859e;
background: #a4c5de; position: relative; }
#wrap img { position: absolute; border: 0; }
</style>
<script type="text/javascript" src="bubble_wrap_min.js"></script>
</head>
<body>
<div id="wrap"></div>
</body>
</html>
// bubble_wrap_min.js
// Fills the game area with bubble images
function loadGame()
{
// Get the game area
var wrap = document.getElementById('wrap');
// Assume the bubble image dimensions and area dimensions
var imgWidth = 75;
var imgHeight = 72;
var rows = 3;
var cols = 8;
// Fill the game area creating img elements with onclick attribute set
for ( var i = 0; i < rows; ++i )
{
for ( var j = 0; j < cols; ++j )
{
// Create the image as a new node
var img = document.createElement('img');
img.src = 'air.jpg';
// Position the image, CSS must specify 'position:absolute' for img
img.style.top = (i * imgHeight) + 'px';
img.style.left = (j * imgWidth) + 'px';
// When user clicks this image, replace it for a popped image
img.onclick = popBubble;
// Insert the new image as child of the game area
wrap.appendChild(img);
}
}
}
// Called when a image is clicked
function popBubble()
{
// Replace the current image for a popped one
this.src = 'pop.jpg';
// This image cannot be popped again
this.onclick = null;
// Play an auditive feedback
var snd = new Audio('pop.mp3');
snd.play();
}
// Initializes the game when the document is loaded
window.addEventListener('load', loadGame, false);
Un ejemplo del juego de estallar una bolsa de burbujas. Correr este ejemplo: versin minimalista, o juego completo.
La funcin que se enva en el segundo parmetro de element.addEventListener() recibe un objeto Event por parmetro. En
el ejemplo del juego de la bolsa de burbujas, el mtodo popBubble() ignora este parmetro. El objeto Event tiene varias
propiedades tiles, entre las que sobresalen currentTarget que es una referencia al objeto que gener el evento
(equivalente a this); el mtodo stopPropagation() que al ser invocado evita que otros nodos sigan procesando el evento; y
preventDefault() que cancela el efecto que tendra normalmente el evento en el navegador, como por ejemplo seguir un
enlace si el elemento fuera un hipervnculo. En algunos eventos el navegador enva un objeto MouseEvent que contiene
informacin sobre el puntero del ratn, como su posicin (clientX, clientY), el botn usado (button), si hubo teclas
modificadoras presionadas en el teclado y otros.
22/09/2015 11:52 a. m.
71 de 99
6 El servidor web
Un servidor web es un programa que responde peticiones HTTP en algn puerto TCP, normalmente el 80. Existe en la
actualidad varias implementaciones populares, entre las que sobresalen Apache HTTP Server, Microsoft Internet Information
Services (IIS), y nginx. Este laboratorio pretende que el estudiante instale, configure y utilice uno de estos servidores para
construir un pequeo sitio web dinmico utilizando FastCGI. En este texto se utilizar nginx.
Una vez instalado el servidor web es necesario ponerlo en marcha. En el caso de nginx basta con invocar su ejecutable. El
usuario notar que al hacerlo el programa termina inmediatamente dando la sensacin de que nada ocurri, sin embargo,
nginx habr iniciado al menos dos procesos homnimos en segundo plano (background), los cuales estarn esperando
solicitudes HTTP en el puerto 80. Esto se puede probar con un navegador que acceda a la direccin http://localhost.
22/09/2015 11:52 a. m.
72 de 99
Desde el punto de vista de la interaccin con el usuario hay dos tipos de programas. Los programas en primer plano
(foreground) cuando son ejecutados mantienen un dilogo con el usuario. La mayora de personas creen que todos los
programas son as. Sin embargo, en ese mismo instante el sistema operativo estar ejecutando un nmero, probablemente
mayor, de programas en segundo plano (background) que no esperan una interaccin directa con el usuario, como por
ejemplo, el ncleo del sistema operativo, servicios de acceso a la red, demonios que ejecutan tareas programadas,
servidores de correo, FTP, etc. El servidor web cabe en esta segunda categora.
Cuando nginx es ejecutado arranca al menos dos procesos. El primero se llama nginx master process y debe ser
ejecutado con permisos de administracin, ya que por poltica de Unix, slo procesos iniciados por el superusuario pueden
abrir sockets en cualquier puerto, mientras que los iniciados por usuarios normales, slo pueden escuchar en puertos
superiores a 1024. El segundo y dems procesos reciben el nombre de nginx working processes, son procesos iniciados
por nginx a nombre de un usuario cualquiera (especificado en la configuracin de nginx) que atienden un cliente web en
cualquier otro puerto, con el fin de liberar el puerto 80 para que est disponible y poder aceptar ms conexiones.
Si se invoca el ejecutable de nginx sin parmetros, tratar de iniciar el servidor web. Si se invoca por segunda vez sin
parmetros, fallar ya que el puerto 80 estar en uso. Si se invoca con el parmetro nginx -h brindar ayuda. La opcin
nginx -V permite ver la versin y los mdulos con que fue compilado el ejecutable. La opcin nginx -s sirve para controlar
al servidor en ejecucin. Otras opciones se discutirn ms adelante.
Las directivas constan de un trmino que significa alguna caracterstica para nginx, seguido por uno o ms valores. El
trmino y los valores se separan por espacios en blanco. Como es de esperar, nginx est dividido en muchos mdulos: core,
webdav, fastcgi, mail, etc., y cada uno tiene directivas para configurarlos. Las directivas de cada mdulo se escriben en el
archivo de configuracin agrupadas dentro de llaves { }, lo que forma un bloque de directivas (directive block), y son
precedidos por el nombre del mdulo. Esta prctica mantiene el orden e incrementa la legibilidad. El siguiente listado
muestra un fragmento de un archivo de configuracin de nginx.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events
{
worker_connections 768;
# multi_accept on;
}
http
{
# Basic settings
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logs
access_log /var/log/nginx/access.log;
22/09/2015 11:52 a. m.
73 de 99
19.
20.
21.
22.
23.
24. }
error_log "/var/log/nginx/error.log";
# Virtual host configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
Del listado anterior se puede leer lo siguiente. La directiva en la lnea 7 slo afecta al mdulo de eventos (Events Module)
de nginx. Las directivas que no estn dentro de llaves (lneas 1 a 3) se dice que estn en el bloque principal (main block) y
tienen un efecto global en el servidor web. Algunas directivas esperan valores numricos como worker_processes en la lnea
2, otras cadenas de caracteres como access_log y error_log en las lneas 18 y 19. Las cadenas se pueden escribir
literalmente, pero si tienen espacios en blanco, puntos y comas, u otros caracteres especiales, debern encerrarse entre
comillas dobles o simples.
Los mdulos de nginx son opcionales, es decir, se pueden instalar o no, y si estn instalados se pueden habilitar o no; a
excepcin de tres mdulos: Core module, Events module y Configuration module, los cuales siempre estn instalados y
siempre habilitados, ya que proveen la funcionalidad mnima de nginx.
Las directivas que se escriban directamente en el bloque http { ... } afectan a todo el mdulo HTTP, como la lnea 3 del
listado anterior, que indica a nginx comprimir los recursos antes de enviarlos al cliente.
6.2.2.1 Servidores virtuales
Un servidor web puede alojar uno o varios sitios web, los cuales se acceden con diferentes dominios. Por ejemplo, una
misma instalacin de nginx podra servir la pgina pblica de la empresa (www.miempresa.com), un sitio para empleados,
clientes y proveedores de la empresa (portal.empresa.com), y un sitio con repositorios de Subversion (svn.miempresa.com).
Es deseable poder configurar cada uno de esos sitios independiente de los dems. Por ejemplo, cada uno debe tener un
diferente directorio fsico donde se encuentran sus recursos, para los dos primeros podra ser importante tener PHP
22/09/2015 11:52 a. m.
74 de 99
no podr utilizar el puerto o la direccin IP como criterio para seleccionar el servidor virtual, pero s el dominio. En este
caso, slo el segundo servidor virtual atiende el dominio portal.miempresa.com en el puerto 80, por lo que nginx cargar el
recurso /home/sites/portal.miempresa.com/login.php?remember_user=yes y lo retornar en un mensaje de respuesta HTTP.
La directiva server_name acepta comodines, por lo que un servidor virtual podra antender todos los dominios que terminen
en o tengan una cadena particular, como:
server_name *.miempresa.com; # or
server_name *miempresa.*; # or
server_name *miempresa*;
La directiva root le indica a nginx dnde se encuentran fsicamente los recursos que deben ser servidos a travs de un
servidor virtual. Es seguido por una ruta, normalmente absoluta, de lo contrario se tomar como relativa al directorio donde
est instalado nginx.
La directiva index le indica a nginx cul recurso o archivo escoger para retornar al cliente cuando se solicita un directorio. Si
se especifican varios archivos, se retornar el primero que se encuentre. A este recurso se le suele llamar index page. Por
ejemplo, si el servidor web recibe la siguiente solicitud HTTP
1. GET /admin/
2. Host: portal.miempresa.com:80
3. User-Agent: Opera/11.01 (iOS)
4.
5.
22/09/2015 11:52 a. m.
75 de 99
text/xml
application/xhtml+xml
application/x-javascript
image/gif
image/jpeg
# ...
xml rss;
xhtml;
js;
gif;
jpeg jpg;
}
default_type application/octet-stream;
}
La directiva default_type le indica a nginx cul MIME type asumir cuando la extensin no se encuentra en el bloque types {
... } o cuando el recurso simplemente no tiene extensin.
el servidor web localizar todos los comentarios que inicien con <--# y tratar de ejecutar el comando que sigue. El
comando include le indica al servidor cargar el archivo que se encuentra en el atributo file="url", o si es un programa,
ejecutarlo. El contenido del archivo o el resultado del programa ser insertado en el documento servido, reemplazando el
comando dentro del comentario.
El autor que quiera utilizar Server Side Includes, deber habilitar el mdulo ssi en la configuracin de nginx, e indicarle en
cules tipos de recursos (MIME types) quiere que el servidor procese esos comandos, de lo contrario se asumirn slo los
text/html. Por ejemplo:
22/09/2015 11:52 a. m.
76 de 99
server
{
server_name miempresa.com www.miempresa.com;
root /home/sites/miempresa.com;
ssi on;
ssi_types text/html application/xhtml+xml application/x-javascript;
}
Aunque SSI es muy eficiente y se puede habilitar para todo un sitio web, es mejor evitarlo para archivos que no lo
requieren. Una prctica comn es nombrar los archivos que tienen Server Side Includes con la extensin .shtml
(contraccin de server html), y habilitar el mdulo ssi slo para ellos, por ejemplo:
server
{
server_name miempresa.com www.miempresa.com;
root /home/sites/miempresa.com;
index index.shtml index.php index.html;
# Habilita Server Side Includes en todos los archivos con extensin .shtml
location ~* \.shtml$
{
ssi on;
}
}
22/09/2015 11:52 a. m.
77 de 99
php /path/to/myfile.php
Lo anterior claramente no es un servidor TCP/IP esperando conexiones en algn puerto, como exige el protocolo FastCGI. El
proyecto PHP-FPM (PHP FastCGI Process Manager) es una alteracin de PHP para Unix que ejecuta un demonio
normalmente en el puerto 9000, el cual espera solicitudes de ejecutar un archivo .php particular con sus respectivos
parmetros. nginx puede comunicarse con PHP-FPM a travs de FastCGI, lo cual se considera una implementacin muy
eficiente, ideada para sitios altamente concurridos.
Para instalar PHP-FPM se puede configurar y compilar su cdigo fuente, o utilizar el administrador de paquetes de su
distribucin de Linux. Por ejemplo, los siguientes comandos instalan y ponen en ejecucin un servidor de PHP-FPM en
Debian/Ubuntu:
sudo apt-get install php5-fpm
sudo /etc/init.d/php5-fpm start
Ahora debe decirle a nginx que cada vez que un visitante solicita un archivo .php, debe contactar al servidor de PHP a
travs de FastCGI en el puerto 9000, para que lo ejecute, y el resultado que se genere de su invocacin, enviarlo al
visitante. Para nuestros efectos, el archivo .php puede estar en cualquier lugar del sitio web, su nico distintivo con los
dems archivos del sitio es su extensin .php. La siguiente configuracin mnima hace este trabajo. Nota: es probable que
las siguientes lneas ya estn presentes en la configuracin por defecto, basta con quitarles los comentarios.
1. server
2. {
3.
server_name miempresa.com www.miempresa.com;
4.
root /home/sites/miempresa.com;
5.
index index.php index.html;
6.
7.
# Ejecuta todos los archivos con extensin .php antes de enviarlos al cliente
8.
location ~* \.php$
9.
{
10.
fastcgi_pass 127.0.0.1:9000;
11.
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
12.
include fastcgi_params;
13.
fastcgi_index index.php;
14.
}
15. }
El bloque location anterior le indica a nginx que antes de servir un archivo con extensin .php, debe contactar a travs de
FastCGI al programa que est corriendo en el puerto 9000, e indicarle que ejecute el archivo .php. Esto ltimo se indica a
travs de parmetros con la directiva fastcgi_param NOMBRE_PARAMETRO valor_parametro. Por ejemplo, la directiva en la lnea
11 le indica a nginx enviar a PHP-FPM la ruta absoluta del archivo .php en el parmetro SCRIPT_FILENAME. Los valores
iniciados con un smbolo de dlar, como $document_root son variables de nginx, las cuales se reemplazan por sus valores
respectivos, en el caso de $document_root por el directorio donde estn los recursos del sitio web (/home/sites
/miempresa.com en este ejemplo), y $fastcgi_script_name por la ruta relativa dentro del sitio del archivo .php solicitado por
el visitante. Otros parmetros son necesarios, el archivo fastcgi_params que trae la instalacin de nginx se encarga de ellos
y funciona para la mayora de sitios.
Para Microsoft Windows no existe una implementacin de PHP-FPM, por lo que el desarrollador puede emularlo a travs de
Cygwin, o utilizar algn paquete "todo en uno", como Easy WEMP (acrnimo de Windows, nginx, MySQL y PHP).
22/09/2015 11:52 a. m.
78 de 99
ser el lenguaje de "scripting" ms usado en servidores web del mundo, bajo el nombre recursivo de PHP: Hypertext
Processor (PHP).
Al correr el ejemplo del Listado 7.1 ocurre lo siguiente. El servidor web recibe un mensaje solicitando el recurso /path/to
/hello_world.php, el cual es un simple archivo de texto. En condiciones normales, el servidor web podra retonarle el
archivo al navegador, el cual no sabra qu hacer con l y le preguntara al usuario un lugar para guardarlo. Sin embargo, el
servidor web est configurado para tratar de forma especial a todos los archivos que terminen con extensin .php. Esta
configuracin indica al servidor web que debe ejecutar los scripts que se encuentran en el archivo .php antes de enviarlo al
navegador.
La configuracin del servidor web tambin le indica cmo encontrar el intrprete de PHP. As el servidor invoca al intrprete
pasndole el archivo /path/to/hello_world.php. El intrprete carga el archivo y lo recorre (parse) buscando scripts de PHP,
los cuales se encuentran nicamente dentro de la etiqueta especial <?php ... ?>. El intrprete ejecuta este cdigo y
reemplaza la etiqueta especial por la salida que gener su ejecucin. Una vez que ha terminado de ejecutar todos los scripts
en el archivo, el resultado regresa al servidor web quien lo despacha al navegador.
El navegador slo recibe el resultado de ejecutar los scripts, no el cdigo fuente PHP que gener el resultado. El lector
puede comprobarlo corriendo el ejemplo del Listado 7.1 y revisando en su navegador el cdigo fuente de la pgina.
Durante muchos aos se utiliz un short tag <? ... ?> en lugar de <?php ... ?> para escribir el cdigo PHP. El uso del
"short tag" debe evitarse a toda costa, ya que genera conflicto con las instrucciones de procesamiento de XML <?xml ... ?>.
De hecho, si se quiere servir documentos XHTML con scripts de PHP, se debe deshabilitar la directiva short_open_tag en la
configuracin del intrprete de PHP (en el archivo php.ini). El Listado 7.2 muestra la fecha y hora del servidor web.
1. <body>
2.
<h1>Hora y fecha del servidor</h1>
3.
<p><?php
4.
$fecha = date('d \d\e F \d\e Y');
5.
$hora = date('h:i:s a');
6.
print("Hoy es " . $fecha . ". Son las " . $hora );
7.
?></p>
8. </body>
Listado 7.2. La hora del servidor en PHP. Co rrer este ejemplo.
El Listado 7.2 muestra otras caractersticas de PHP. En el ejemplo del hola mundo (Listado 7.1) el prrafo se gener dentro
del script de PHP (lnea 13), mientras que en el ejemplo de la hora (Listado 7.2) el script se escribi dentro de un elemento
p. Esto muestra que el autor puede intercalar cdigo PHP y (X)HTML a conveniencia. Algunos programadores prefieren abrir
una nica etiqueta <?php ... ?> y escribir mucho cdigo PHP, otros prefieren escribir cdigo (X)HTML y abrir etiquetas <?php
... ?> slo para el mnimo cdigo PHP necesario. El segundo mtodo es quiz ligeramente ms eficiente y es la convencin
que se tomar en este texto.
22/09/2015 11:52 a. m.
79 de 99
Las lneas 4 y 5 del Listado 7.2 invocan una funcin estndar de PHP: date(), la cual retorna un string con la fecha u hora
en el formato que se le indique por parmetro. PHP tiene una rica biblioteca de funciones cuya documentacin es quiz una
de las mejores que existe en el mundo.
El string resultado de invocar a date() en la lnea 4 del Listado 7.2 se almacena en la variable $fecha. PHP exige anteponer
el smbolo de dlar ($) a un identificador para distinguirlo como una variable, de la misma forma que ocurre en Perl y en
Unix shell scripting, con el objetivo de hacer ms eficiente el reconocimiento de las variables a la hora de ejecutar el cdigo.
Al igual que en JavaScript, las variables pueden almacenar valores de cualquier tipo de datos, incluso cambiar en el tiempo.
Una variable se crea simplemente asignndole un valor.
La lnea 6 del Listado 7.2 imprime un texto resultado de concatenar unos strings literales con las variables $fecha y $hora
utilizando el operador punto (.). Esto crea la primera diferencia con JavaScript, que utiliza el operador de suma (+) para la
concatenacin. El ejemplo anterior pudo haberse escrito de otra forma muy comn:
1. <body>
2.
<h1>Hora y fecha del servidor (2)</h1>
3.
<p><?php
4.
$fecha = date('d \d\e F \d\e Y');
5.
$hora = date('h:i:s a');
6.
print("Hoy es $fecha. Son las $hora");
7.
?></p>
8. </body>
Listado 7.3. La hora del servidor con interpolacin de variables. Correr este ejemplo.
El ejemplo del Listado 7.3 slo cambia la lnea 6 del Listado 7.2. En la nueva versin se insertaron las variables
directamente en el string. A esto se le llama interpolacin de variables o sustitucin de variables y el intrprete de
PHP lo hace nicamente en las cadenas con comillas dobles (como en "$var") y no en cadenas con comillas simples (como
en '$var'). Lo mismo aplica para las secuencias de escape como "\n".
El desarrollador web debe tener clara esta diferencia, ya que JavaScript trata de forma idntica a las cadenas literales con
comillas dobles o simples, mientras que PHP hace interpolacin de variables y secuencias de escape en una de ellas y no en
la otra. El lector podra estar pensando en utilizar siempre comillas dobles para evitar sorpresas, sin embargo, debe tener
en cuenta que el procesamiento de las cadenas literales con comillas simples es ms eficiente que con comillas dobles.
22/09/2015 11:52 a. m.
80 de 99
Antes de publicar cdigo PHP en el sitio web o en el repositorio de control de versiones, el desarrollador siempre debera
chequear sus programas con el intrprete de PHP, lo cual puede hacerse en la lnea de comandos de la siguiente forma:
php /path/to/file.php
El desarrollador tampoco podr verificar un documento .php contra los validadores del Consorcio Web (como Unicorn), pero
s su salida. Es decir, que el desarrollador deber hacer dos verificaciones, la primera es llamar al intrprete de PHP en lnea
de comandos para verificar que su cdigo PHP sea correcto, y luego la salida que su programa genera debe verificarla contra
los estndares del Consorcio Web. Una tercera verificacin podra deberse si se tiene cdigo JavaScript, inspeccionando la
bitcora de errores del navegador.
Al igual que JavaScript, PHP diferencia maysculas y minsculas (case sensitive), y la aritmtica se hace en punto flotante,
es decir, 5 / 2 genera 2.5 y no 2 como ocure en C. A diferencia de JavaScript, PHP s permite que un string se expanda
varias lneas, y en tal caso, los espacios en blanco y cambios de lnea pasan a formar parte natural del string, por ejemplo:
$table = /* ... */;
$condition = /* ... */;
$query = "
SELECT *
FROM $table
WHERE $condition
";
equivale a haber escrito el siguiente cdigo en una sola lnea, pero que resulta ms ilegible:
$query = "\n\tSELECT *\n\tFROM $table\n\tWHERE $condition\n";
Al igual que JavaScript, las variables pueden almacenar valores de diferentes tipos de datos a lo largo de la ejecucin del
script, y las conversiones de datos se hacen automticamente de acuerdo al contexto. En PHP el operador de suma (+) se
utiliza slo para valores numricos y no hace concatenacin, lo cual es responsabilidad del operador punto (.). Por ejemplo:
<p>
<?php
# Una variable que almacena un valor numrico
$telefono = 50628241202;
# Obtiene el cuarto digito (en la posicion 3) conviertiendo el nmero en un string
# la conversion la hace PHP automaticamente al usar algo en un contexto string
$tipo_tel = substr($telefono, 3, 1);
# Comparacin de un string con un nmero: el string se convierte a nmero
if ( $tipo_tel != 8 )
echo "No se puede enviar mensajes de texto al telfono $telefono.";
?>
</p>
Listado 7.4. Conversin automtica de tipos de datos. Correr este ejemplo.
El lector habr notado que en algunos ejemplos se ha utilizado print y en otros echo para generar la salida que recibir el
navegador. No son funciones realmente, son constructos del lenguaje y por ende pueden utilizarse con o sin parntesis. La
diferencia radica en que print recibe nicamente un parmetro de tipo string y retorna siempre el entero 1; mientras que
echo no tiene un valor de retorno y puede recibir un nmero arbitrario de parmetros de cualquier tipo separados por
comas, los cuales tratar de convertir a string automticamente. En general, print() es un constructo del lenguaje utilizado
para simular una funcin en un contexto donde se requiere una, mientras que echo es un constructo del lenguaje que no
puede utilizarse en el contexto de una funcin y debe obligatoriamente usarse sin parntesis si recibe dos o ms
22/09/2015 11:52 a. m.
81 de 99
parmetros. Exceptuando esas extraas restricciones, en la mayora de contextos puede utilizarse cualquiera de los dos, y la
escogencia la hace el programador de acuerdo a sus gustos personales.
22/09/2015 11:52 a. m.
82 de 99
echo '
Los objetos de PHP se parecen mucho a los de Java. Un objeto es una instancia de una clase, la cual puede tener herencia
y polimorfismo con otras clases. Los objetos se crean con el operador new y sus miembros se acceden con el operador ->.
Este tema se explica ms adelante.
El tipo de datos y valor especial null sirve para indicar que una variable no tiene valor. Si se trata de hacer referencia a una
variable que no existe, PHP puede o no generar un warning de acuerdo a su configuracin, y el valor de reemplazo de la
variable no existente es null, el cual se puede escribir en cualquier combinacin de maysculas y minsculas.
Cuando se utiliza un valor de un tipo de datos en un contexto donde se espera otro, PHP trata de hacer conversiones
automticamente; lo cual funciona bien en la mayora de casos para los valores primitivos. El programador puede forzar la
conversin de datos utilizando explicit type cast, anteponiendo el tipo de datos entre parntesis a la expresin que se quiere
convertir, como en el ejemplo del Listado 7.6.
$num = 5 / 2;
echo "5 / 2 == $num\n";
// prints 2.5
7.1.4 Operadores
El programador puede escribir los mismos operadores que usa en C o JavaScript sin cambios en PHP. Las diferencias son
mnimas, como las que se exponen a continuacin.
El operador de concatenacin en PHP es el punto (.), as el operador de suma (+) pretende slo recibir operandos
numricos, de lo contrario, tratar de convertirlos a nmeros.
Al igual que en JavaScript, el operador de igualdad == indica si dos valores son el mismo an despus de hacer
conversiones, as la expresin "+12.3" == 12.30 se evaluar como verdadera. El operador de identidad === se evala
verdadero slo si sus operandos son iguales sin hacer conversiones.
Los operadores lgicos clsicos && y || trabajan de la misma forma que en otros lenguajes de programacin. Sin embargo,
PHP introduce los operadores lgicos nombrados and y or (que tambin pueden escribirse en maysculas: AND y OR), que
tienen una prioridad menor, por lo que pueden causar conflictos si se combinan operadores clsicos con los nombrados en
una misma expresin. Se aconseja al programador utilizar slo los operadores clsicos a menos de que se entienda bien el
efecto del operador nombrado.
Los ciclos en PHP se realizan con las mismas clusulas de C: while, do-while y for, las cuales mantienen la misma sintaxis.
PHP agrega una estructura de control ms: foreach, la cual sirve para iterar arreglos y objetos, como se ver ms adelante
22/09/2015 11:52 a. m.
83 de 99
7.1.6 Arreglos
En PHP los arreglos son contenedores asociativos, es decir, son contenedores de parejas key => value, donde las llaves (key)
pueden ser nmeros o strings, y si se omiten, PHP asume valores enteros. Un arreglo se crea simplemente asignndole
valores a sus elementos o con el constructo array(). Para crear una pareja key => value y agregarla al arreglo, se emplea
la siguiente notacin:
$arr[key] = value;
Si se asigna un valor a una llave que ya existe dentro del arreglo, no se inserta de nuevo, si no que se reemplaza su valor
anterior. Si se omite la llave en la asignacin, PHP busca el ltimo entero asociado en el arreglo y asigna el subsecuente al
valor. Esto se ilustra en el Listado 7.8.
// Crea un arreglo asignndole un valor
$notas['luis'] = 9.5;
echo "\n\$notas['luis'] = 9.5;\n\$notas = "; print_r($notas);
// Crea otra asociacin (key,value) y la agrega al arreglo
$notas['ana'] = 10.0;
echo "\n\$notas['ana'] = 10.0;\n\$notas = "; print_r($notas);
// Llave 'luis' ya existe en arreglo, actualiza valor
$notas['luis'] = 6.5;
echo "\n\$notas['luis'] = 6.5;\n\$notas = "; print_r($notas);
// Asocia un valor a la mayor clave numrica libre en el arreglo
$notas[] = 'ana';
echo "\n\$notas[] = 'ana';\n\$notas = "; print_r($notas);
// Asocia la posicin numrica dada con el valor
$notas[3] = 'diana';
echo "\n\$notas[3] = 'diana';\n\$notas = "; print_r($notas);
// Asocia en la posicin 1 4?
$notas[] = 'fiona';
echo "\n\$notas[] = 'fiona';\n\$notas = "; print_r($notas);
Listado 7.8. Insertar y actualizar elementos en un arreglo utiliz ando el operador corchetes y asignacin. Correr este ejemplo.
La segunda forma de crear un arreglo es utilizando el constructo array(k1 => v1, k2 => v2, ..., kN => vN), que recibe las
parejas llave=valor utilizando la notacin key => value que asemeja una asignacin, pero en lugar de ser una asignacin
directa indica actualizar el valor del ndice o llave key. En el constructo array(), si una llave se omite, se asume el prximo
ndice que sigue al ltimo entero utilizado. El resultado final del Listado 7.8 se podra escribir utilizando array() como se
aprecia en el Listado 7.9.
// Crea un arreglo utilizando el constructo array()
$notas = array('luis' => 6.5, 'ana' => 10.0, 'ana', 3 => 'diana', 'fiona');
echo "\n\$notas = "; print_r($notas);
// Se puede asociar nuevos elementos a un arreglo creado con array()
echo "\nAgregando notas para diana y fiona:";
$notas['diana'] = 8.5;
$notas['fiona'] = 5.0;
// Imprime todos los elementos del arreglo utilizando el ciclo foreach
foreach($notas as $key => $value)
echo "\n
$key: $value";
// Calcula el promedio de la clase
$sum = 0.0;
$count = 0;
foreach($notas as $key => $value)
{
if ( gettype($value) == 'double' )
{
$sum += $value;
++$count;
}
}
printf("\n\nEl promedio de los $count alumnos es %.2f", $sum / $count);
Listado 7.9. Crear un arreglo utilizando el constructo array() y recorrerlo con el ciclo foreach-as. Correr este ejemplo.
PHP provee el ciclo foreach-as, el cual recorre un arreglo por cada una de sus parejas key => value y permite al
programador hacer algo con ellas en cada iteracin del ciclo. El orden de recorrido es el mismo en que se encuentran los
elementos en el arreglo, y puede alterarse con funciones de ordenamiento.
Las llaves en un arreglo asociativo slo pueden ser enteras o string, pero el valor puede ser de cualquier tipo de datos,
incluso otro arreglo. Esto permite representar matrices o arreglos de ms dimensiones.
22/09/2015 11:52 a. m.
84 de 99
7.1.7 Funciones
Las funciones en PHP se declaran con la palabra reservada function seguido por la lista de parmetros entre parntesis, de
la misma forma que se hace en JavaScript. El Listado 7.10 ilustra la funcin factorial() y su uso para imprimir los primeros
19 factoriales.
1. <body>
2.
<h1>Factoriales</h1>
3.
<ul>
4.
<?php
5.
# Retorna el factorial de $n
6.
function factorial($n)
7.
{
8.
return $n > 0 ? $n * factorial($n - 1) : 1;
9.
}
10.
11.
// Imprime los primeros 20 factoriales incluyendo el 0
12.
for ( $i = 0; $i < 20; ++$i )
13.
echo "<li>$i! = ", factorial($i), "</li>\n";
14.
?>
15.
</ul>
16. </body>
Listado 7.10. Nmeros factoriales con una funcin recursiva en PHP. Correr este ejemplo.
En JavaScript el manejo de valores o referencias es implcito, es decir, el lenguaje se reserva su manejo y el programador
no puede alterarlo. En cambio, en PHP el manejo de valores y referencias es explcito, es decir, el programador debe indicar
cundo quiere hacer una copia de un valor o cuando quiere tener una referencia hacia el valor original. Como es de esperar,
las referencias se crean con el operador ampersand (&), como se aprecia en el ejemplo del php_byvalue_byreference.
Este problema es un error comn de programacin, debido a PHP rompe la norma de la mayora de lenguajes con los cuales
podra estar familiarizado el desarrollador. Hay varias soluciones. Si es factible, se recomienda pasar por parmetro el valor
que requiere la funcin, as se mantiene la modularidad del cdigo y se reduce la dependencia de variables globales, como
se hace en el Listado 7.12.
1. <body>
2.
<h1>Factoriales</h1>
3.
<ul>
4.
<?php
5.
// Variable global
6.
$count = 25;
7.
8.
function factorial($n)
9.
{
10.
return $n > 0 ? $n * factorial($n - 1) : 1;
11.
}
12.
13.
function print_factorials($count)
14.
{
15.
// Error: $count no esta definida localmente
22/09/2015 11:52 a. m.
85 de 99
16.
for ( $i = 0; $i < $count; ++$i )
17.
echo "<li>$i! = ", factorial($i), "</li>\n";
18.
}
19.
20.
print_factorials($count);
21.
?>
22.
</ul>
23. </body>
Listado 7.12. Pasar variables globales po r parmetro a una funcin. Correr este ejemplo.
Si por alguna razn se necesita trabajar con variables globales, se le puede indicar a la funcin que la variable $count no
est definida en el contexto local si no en el global, lo cual se hace con la palabra reservada global, como se aprecia en la
lnea 16 del Listado 7.13. El uso de variables globales se considera una mala prctica de programacin.
1. <body>
2.
<h1>Factoriales</h1>
3.
<ul>
4.
<?php
5.
// Variable global
6.
$count = 25;
7.
8.
function factorial($n)
9.
{
10.
return $n > 0 ? $n * factorial($n - 1) : 1;
11.
}
12.
13.
function print_factorials()
14.
{
15.
// Hace a $count accesible en el contexto local
16.
global $count;
17.
18.
// Error: $count no esta definida localmente
19.
for ( $i = 0; $i < $count; ++$i )
20.
echo "<li>$i! = ", factorial($i), "</li>\n";
21.
}
22.
23.
print_factorials();
24.
?>
25.
</ul>
26. </body>
Listado 7.13. Uso de variables globales. Correr este ejemplo.
PHP provee algunas variables globales que son accesibles desde cualquier contexto, es decir, sin tener que declararlas
primero con la palabra reservada global. Se les conocen como variables superglobales y son arreglos asociativos con
informacin muy til para el programa. Se listan en la Tabla 7.2.
Arreglo
Descripcin
$GLOBALS
Sirve para acceder a las variables globales, en especial si se quiere acceder a una variable global y existe una homnima
en el contexto local.
$_SERVER
Contiene variables enviadas por el servidor web al intrprete de PHP, como $_SERVER['PHP_SELF'] que tiene la ruta del
programa PHP relativa a la raz del sitio, el nombre del servidor web ($_SERVER['SERVER_NAME']), detalles del
navegador que solicit ejecutar el programa PHP ($_SERVER['HTTP_USER_AGENT']), el IP de la mquina del cliente
($_SERVER['REMOTE_ADDR']) y muchos otros.
$_GET
Aloja las variables pasadas al script por parmetro en el URL (mtodo HTTP GET).
$_POST
Aloja las variables pasadas al script por parmetro utilizando el mtodo HTTP POST.
$_FILES
Aloja informacin sobre los potenciales archivos que se hayan enviado (uploaded) por el mtodo HTTP POST.
$_COOKIE
Un arreglo con variables y valores que el navegador aloja por peticin del sitio web.
Las variables ambiente que dispone el intrprete de JavaScript. Son dependientes del sistema operativo.
Tabla 7.2. Arreglos asociativos superglobales en PHP
Siempre que se va a usar una variable cuyo valor fue provisto por una fuente externa, como un parmetro, debe evitarse
que su valor sea ejecutado por el intrprete de JavaScript o genere cdigo (X)HTML/JavaScript, ya que permite a un
atacante inyectar cdigo maligno que podra revelar informacin confidencial de su sitio web u otro tipo de dao. PHP
provee varias funciones que convierten cdigo en una representacin no ejecutable, como htmlentities() que reemplaza
los caracteres especiales (<, >, &) por sus entidades correspondientes (<, >, &).
7.1.9 Objetos
22/09/2015 11:52 a. m.
86 de 99
Los objetos en PHP utilizan prcticamente la misma sintaxis de Java, con algunas variaciones de C++. Los objetos son
instancias de clases. Una clase se declara con la palabra reservada class seguida por un identificador. Las propiedades
(miembros de datos) y mtodos de la clase, se deben anteceder con el tipo de acceso que deben tener: private, protected o
public. Si se omite, PHP asume public.
Los mtodos se declaran como cualquier otra funcin de PHP, slo que dentro del cuerpo de la clase. Un mtodo de una clase
a diferencia de una funcin normal, tiene acceso a tres identificadores reservados: $this es una referencia hacia la instancia
del objeto al que se le invoc el mtodo, y se utiliza para acceder a sus propiedades y otros mtodos. self:: es una
referencia hacia la clase misma y sirve para acceder a sus miembros estticos. parent:: permite acceder a propiedades y
mtodos de la clase base.
Para instanciar un objeto se utiliza el operador new clase(parametros), envindole los parmetros que recibe la clase en el
constructor. Un constructor es un mtodo con el nombre especial __construct, el cual se encarga de inicializar los miembros
de datos del objeto. Aunque se puede utilizar un mtodo con el mismo nombre de la clase como constructor, no se
recomienda esta prctica, ya que versiones recientes de PHP lo interpretan como un mtodo normal.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
class Player
{
protected $nickname, $email, $score;
function __construct($nickname, $email, $score = 0)
{
$this->nickname = $nickname;
$this->email = $email;
$this->score = $score;
}
function increaseScore($by = 1) { $this->score += $by; }
function getNickname() { return $this->nickname; }
function getScore() { return $this->score; }
}
$players[] = new Player('pinocho', 'pinocho@cajafishel.com');
$players[] = new Player('chema', 'chema@semeolvido.com');
$players[] = new Player('osqui', 'dumbo@tlc.com');
$bets = rand(30, 100);
echo count($players), " jugadores, $bets apuestas... ";
for ( $i = 0; $i < $bets; ++$i )
{
$winner = $players[ rand(0, count($players) - 1) ];
$winner->increaseScore();
}
echo "Resultados:\n";
for ( $i = 0; $i < count($players); ++$i )
echo '
', $players[$i]->getNickname(), ': ', $players[$i]->getScore(), "\n";
Listado 7.14. Ejemplo de clases y objetos en PHP. Correr este ejemplo.
22/09/2015 11:52 a. m.
87 de 99
El procedimiento para trabajar con archivos en PHP es el mismo que en otros lenguajes: abrir el archivo con la funcin
fopen(), leer o escribir bytes en l (fread(), fwrite(), fprintf(), etc.) y cerrar el archivo con la funcin fclose(). Todas
estas funciones necesitan saber en cul archivo trabajar. PHP utiliza un tipo de variable especial llamada "recurso"
(resource) para representar archivos o registros de una base de datos.
La funcin fopen() retorna un recurso (resource) hacia el archivo cuya ruta est en el primer parmetro. Pero si fopen()
falla al abrir el archivo, retorna false. Es una prctica comn detener la ejecucin del script con la funcin die() en caso de
no poder acceder a un recurso importante (lnea 3 del Listado 7.15) ya que permite rpidamente a los desarrolladores
identificar y solucionar el problema; sin embargo, esto nunca debe hacerse. Lo adecuado es presentar una pgina de error
amigable al visitante, y quiz enviar un correo electrnico al administrador del sitio web para avisar del problema. Las
principales razones porque fopen() falla al abrir un archivo es por falta de permisos, falta de espacio en disco o porque el
nombre del archivo es invlido. Estos problemas son responsabilidad del programador y no del visitante.
El Listado 7.16 muestra como recorrer la bitcora creada en el Listado 7.15 y presentar su contenido en una tabla XHTML.
La lectura se hace en un ciclo hasta encontrar el final del archivo (lnea 11). En cada iteracin del ciclo se obtiene una lnea
del archivo y se imprime como una fila de la tabla, a excepcin de que sea una lnea vaca.
1. // Abrir el archivo para mostrar su contenido
2. $log_file = fopen('log_file.txt', 'r')
3.
or die('Error: No se pudo abrir log_file.txt');
4.
5. echo "<table><thead><tr>"
6.
, "<th></th><th>Fecha</th><th>IP</th><th>Puerto</th><th>Agente
usuario</th>"
7.
, "</tr></thead><tbody>\n";
8.
9. // Imprimir cada lnea en una fila de una tabla XHTML
10. $count = 0;
11. while ( ! feof($log_file) )
12. {
13.
$line = fgets($log_file);
14.
$line = trim($line);
15.
if ( strlen($line) == 0 ) continue;
16.
$line = str_replace("\t", '</td><td>', $line);
17.
echo "<tr><th>", ++$count, "</th><td>$line</td></tr>\n";
18. }
19.
20. echo "</tbody></table>\n";
21. fclose($log_file);
Listado 7.16. Leer un archivo de texto en PHP. Correr este ejemplo.
Qu pasa si dos programas escriben simultneamente en un mismo archivo? Si no se hace de forma controlada, la
respuesta ser que el archivo se corrompe. En un ambiente web, una misma pgina puede ser visitada por uno, varios o
miles de usuarios simultneamente. Cada uno provoca una ejecucin distinta del mismo script PHP. Por eso es tan
importante evitar que dos procesos traten de escribir el mismo archivo simultneamente, o que uno escriba mientras otros
estn leyendo.
PHP provee la funcin flock() que bloquea un archivo para uso exclusivo (LOCK_EX) o lo desbloquea (LOCK_UN), y funciona de
la siguiente forma. Supngase que un proceso 1 pide bloquear un archivo con flock(), el cual le otorga permiso de
escritura. Mientras el proceso 1 est escribiendo, un proceso 2 solicita bloquear el archivo para escritura; flock() pone en
espera al proceso 2 hasta que el proceso 1 haya terminado de escribir. Una vez que proceso 1 desbloquee el archivo
invocando a flock() con el parmetro LOCK_UL, flock() sacar de la cola de espera al proceso 2 bloqueando el archivo de
nuevo.
El uso de flock() produce una serializacin de procesos, y por ende, introduce tiempos de espera que podran ser notorios
para el visitante. Para reducir estos tiempos al mximo se recomienda bloquear el archivo inmediatamente antes de hacer la
escritura y desbloquearlo inmediatamente despus de escribir en l; es decir, se debe evitar bloquear un archivo desde que
22/09/2015 11:52 a. m.
88 de 99
inicia el script, y desbloquearlo al final de ste. El Listado 7.17 muestra el ejemplo de la bitcora (Listado 7.15) utilizando
candados.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Como se podr notar en la lnea 6 del Listado 7.17, la solicitud de bloquear un archivo debe hacerse en un if, debido a que
flock() retorna false en caso de que el mecanismo de candados no sea implementado por el sistema operativo o el sistema
de archivos, como ocurre en FAT32 o NFS (Network File System).
22/09/2015 11:52 a. m.
89 de 99
+--------------------+
| information_schema |
| mysql
|
| Universidad
|
+--------------------+
3 rows in set (0.01 sec)
mysql> USE Universidad;
Database changed
mysql> GRANT ALL ON Universidad.* TO 'php_user' IDENTIFIED BY 'php_user_password';
Query OK, 0 rows affected (0.00 sec)
mysql> QUIT
Bye
$ mysql -u php_user -p
Password:
mysql> QUIT
Bye
Es probable que su sitio web se componga de muchos archivos .php y varios de ellos necesiten acceder a la base de datos.
Para evitar redundar cdigo, es conveniente guardar las credenciales en un archivo reutilizable, por ejemplo
db_credentials.php, cuyo contenido puede ser como el mostrado en el Listado 7.18. Es muy importante que estas variables
estn dentro de la etiqueta <?php...?>, de lo contrario cualquier visitante que trate de acceder a l, ver informacin
sensible. Y si por alguna razn el servidor de PHP dejara de funcionar, el servidor web podra enviarle el archivo
db_credentials.php ntegro al navegador para que lo almacene en algn lugar del disco. Por esto, de ser posible el archivo
con credenciales debera estar en alguna carpeta del sistema de archivos que no es parte del sitio web, y debera tener
permisos de lectura y escritura el administrador del sistema operativo (root en Unix) y permiso de lectura para el usuario
del servidor web (algo como www-data) nicamente.
<?php
$db_host
$db_name
$db_user
$db_pass
?>
=
=
=
=
'localhost';
'Universidad';
'php_user';
'php_user_password';
Listado 7.18. Archivo reutilizable con las credenciales para acceder a la base de datos. Al correr este ejemplo debera obtener una pgina vaca.
Para comunicarse con el DBMS, PHP provee un conjunto de funciones que varan de un DBMS a otro, o la clase genrica
PDO (PHP Data Objects) que provee una misma interfaz para acceder a varios DBMS.
// Este PHP se llama solo 1 vez para crear el esquema de la base de datos.
// Cargar las credenciales de la base de datos
require_once('db_credentials.php');
// Conectarse al servidor de base de datos (DBMS)
$db_connection = mysql_connect($db_host, $db_user, $db_pass)
or die("No se pudo conectar al DBMS: " . mysql_error() );
// De todas las bases de datos que hay en el DBMS, escoger la de Universidad
// Esto equivale a escribir 'USE Universidad;' en un cliente de MySQL
mysql_select_db($db_name)
or die("No se pudo seleccionar la base de datos: " . mysql_error() );
// Truco: si se pasa el parametro drop_tables=true, se recrea la base de datos
$drop_tables = isset($_GET['drop_tables']) && $_GET['drop_tables'] == 'true';
22/09/2015 11:52 a. m.
90 de 99
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
// Borrar las tablas es util por si el webmaster quiere empezar el sitio de cero
if ( $drop_tables )
{
// Obtener la lista de tablas existentes para eliminarlas
$result = mysql_query("SHOW TABLES FROM $db_name")
or die("No se pudo obtener la lista de tablas: " . mysql_error() );
// Por cada tabla encontrada en la base de datos, eliminarla
while ($row = mysql_fetch_row($result))
{
// mysql_fetch_row() retorna un arreglo con un valor por cada atributo
$table_name = $row[0];
mysql_query("DROP TABLE $table_name") or die( mysql_error() );
echo "<li>Tabla $table_name: <span class=\"warning\">Eliminada</span>.</li>\n";
}
// Ya los registros con los nombres de las tablas no seran usados mas, liberarlos
mysql_free_result($result);
}
// Crear las tablas que no existen
// Crear cada tabla de la base de datos Universidad
$query =
'CREATE TABLE IF NOT EXISTS Estudiante (
Carne CHAR(6),
Nombre VARCHAR(50) NOT NULL,
Correo VARCHAR(100) UNIQUE,
Promedio REAL DEFAULT 0.0,
CONSTRAINT PRIMARY KEY (Carne),
INDEX(Nombre(45))
);';
mysql_query($query) or die("No se pudo crear la tabla Estudiante: " . mysql_error());
echo "Tabla Estudiante: creada exitosamente.<br/>\n";
$query =
'CREATE TABLE IF NOT EXISTS Profesor (
Cedula INT(9),
Nombre VARCHAR(50) NOT NULL,
Correo VARCHAR(100) NOT NULL UNIQUE,
CONSTRAINT PRIMARY KEY (Cedula),
INDEX(Nombre(45))
);';
mysql_query($query) or die("No se pudo crear la tabla Profesor: " . mysql_error());
echo "Tabla Profesor: creada exitosamente.<br/>\n";
// Es buena practica cerrar la conexion tan pronto como se deja de usar
mysql_close($db_connection);
Listado 7.19. Creacin de tablas en una base de datos MySQL vaca. Obtener el ejemplo completo.
La lnea 6 del Listado 7.19 invoca la funcin mysql_connect($host, $user, $pass) para intentar establecer una conexin con
el servidor de base de datos MySQL que est en la computadora local (puesto que el valor de $db_host es 'localhost'), con
el usuario y contrasea que se crearon para uso exclusivo de los scripts de PHP. Si mysql_connect() logra establecer la
conexin, retorna un recurso de PHP (resource) que representa a la conexin y puede usarse subsecuentemente. Si no se
puede establecer la conexin, mysql_connect() retorna false y PHP verifica la segunda condicin del or en la lnea 7, que
detiene la ejecucin del script con mensaje de error para el navegador. Como se dijo antes, este mensaje es til para el
desarrollador, pero poco amigable para el visitante.
Si la ejecucin alcanza la lnea 11 del Listado 7.19, indica que la conexin con el DBMS fue establecida exitosamente. El
DBMS puede tener muchas bases de datos a su cargo, y es necesario indicarle con cual de todas ellas se quiere trabajar con
la funcin mysql_select_db($db_name).
A partir de la lnea 40 en adelante, se empiezan a crear las tablas de la base de datos Universidad, pero si ya existen, se
mantienen inalteradas. Sin embargo, pueda que por alguna razn el administrador del sitio web de la Universidad
(webmaster) quiera limpiar la base de datos y empezar de cero. Para efectos ilustrativos, si se ha provisto el parmetro
create_schema.php?drop_tables=true en el URL (de esto se hablar luego) se destruirn todas las tablas existentes de la
base de datos sin confirmacin alguna, lo cual no es un buen diseo, pero se hace aqu con propsitos ilustrativos.
En caso de que el administrador solicite recrear las tablas, el mtodo ms eficiente es eliminarlas de golpe (DROP TABLE) y
volverlas a crear vacas. Para poder borrarlas se necesita conocer el nombre de cada una de ellas. El script podra tener
estos nombres en un arreglo, o bien, solicitarlos al DBMS mediante una consulta SHOW TABLES de MySQL. Cada cual tiene sus
ventajas y desventajas. Aqu se seguir la segunda.
La consulta SHOW TABLES opera de la misma forma que una consulta SELECT de SQL. La consulta es ejecutada con la funcin
mysql_query($sql_query), la cual retorna un recurso que representa el resultado de la consulta, a veces llamado "record
set". En la lnea 21 del Listado 7.19, este recurso se almacena en una variable $result.
Es importante hacer notar que $result almacena un recurso, no los datos que se obtuvieron de la consulta. En el modelo
relacional, los datos resultado de una consulta son una tabla temporal, y aunque algunos DBMS permiten acceder a todos
ellos como si fuesen una matriz en memoria aleatoria (RAM, Random Access Memory), es ms eficiente recorrerlos una fila
a la vez. Cada invocacin a la funcin mysql_fetch_row($query_result) trae de la base de datos la prxima fila resultado de
una consulta, y la retorna en un arreglo que permite acceder a cada valor por un ndice que equivale al nmero de la
columna. Para el caso de SHOW TABLES slo se retorna una columna con el nombre de cada tabla presente en la base de
22/09/2015 11:52 a. m.
91 de 99
datos. La lnea 28 del Listado 7.19 muestra cmo acceder a este valor. Si se quiere acceder al valor por el nombre de la
columna en lugar de un ndice, utilcese la funcin mysql_fetch_assoc($query_result), que puede tener el efecto de hacer al
cdigo ms portable.
Una vez que se ha obtenido el nombre de la tabla, se emite otra consulta DROP TABLE para eliminarla de la base de datos
(lnea 30). Ntese que la invocacin a mysql_fetch_row() se hace en un ciclo, ya que es muy probable que existan varias
tablas en la base de datos. Cuando se ha terminado de procesar la ltima de ellas, mysql_fetch_row() retornar false en
lugar de un arreglo de valores.
La lnea 35 del Listado 7.19 invoca la funcin mysql_free_result($query_result) para liberar las estructuras de datos en
memoria que alojan el resultado de la consulta obtenido en la lnea 21 con mysql_query(). Si se omite esta invocacin, el
intrprete de PHP lo har automticamente cuando el script termine su ejecucin.
En sntesis, el cdigo de las lneas 18 a 36 del Listado 7.19 se ejecuta slo cuando se ha solicitado eliminar las tablas
existentes de la base de datos, obteniendo el nombre de cada una de ellas y eliminndolas con DROP TABLE. Una vez que se
han eliminado, el programa sigue su ejecucin normal en la lnea 40, que emite otras consultas (CREATE TABLE) con la
misma funcin mysql_query(), pero debido a la naturaleza de la instruccin CREATE TABLE de SQL, no se generan registros de
datos como resultado, sino los valores true y false indicando respectivamente si la creacin de la tabla fue exitosa o no.
Como puede inferirse, la funcin mysql_query() se utiliza para ejecutar cualquier tipo de consulta SQL: crear tablas, insertar
valores, actualizar valores, eliminar valores y obtener datos.
Para mysql_query() la consulta es un simple string que pasa directamente al DBMS. La sintaxis de dicha consulta es
completamente dependiente del DBMS en uso. El desarrollador web debe consultar la documentacin oficial de su DBMS
para comprobar su validez u otras opciones tiles. En los ejemplos de este documento se ha utilizado MySQL cuya sintaxis
se puede consultar en lnea.
Finalmente la lnea 64 del Listado 7.19 desconecta al intrprete de PHP del servidor de bases de datos con la funcin
mysql_close(), la cual libera recursos y permite que el DBMS pueda aceptar otras conexiones; aspecto importante cuando
se atienden miles de visitantes simultneamente en un sitio web.
22/09/2015 11:52 a. m.
92 de 99
3.
$password = isset($_GET['password']) ? $_GET['password'] : '';
4.
if ( $username != '' && $password != '' )
5.
{
6.
echo "<p>Bienvenido(a) <strong>$username</strong> a nuestro sitio seguro. ";
7.
echo "(No eres <a href=\"login1.php\">$username</a>?).</p>";
8.
}
9.
else
10.
{
11.
echo <<<_EOT
12.
<form method="get" action="login1.php">
13.
<p><label>Usuario: <input type="text" name="username"/></label></p>
14.
<p><label>Contrasea: <input type="password" name="password"/></label></p>
15.
<p><input type="submit" value="Enviar"/></p>
16.
</form>
17. _EOT;
18.
}
19. ?></body>
Listado 7.20. Un fo rmulario web minimalista. Correr este ejemplo.
Un formulario web (form) se compone de varios campos de entrada (input, select y textarea) en los que el visitante
ingresa o escoge informacin. En el caso del Listado 7.20 el formulario consta de un campo de texto con nombre username
(lnea 13), un campo de texto para ingresar contraseas llamado password (lnea 14) y el botn de "submit" (lnea 15). El
usuario llena estos campos y cuando est listo, presiona el botn de enviar (submit). Esto causa que el navegador recopile
el valor de todos los campos del formulario como parejas nombre_campo=valor y las enve a algn programa en el servidor
web para que las procese. El URL de este programa se especifica en el atributo action del elemento form (lnea 12), que en
el caso del Listado 7.20 es el programa mismo.
Cmo hace el programa indicado en el atributo action para recuperar los datos ingresados por el visitante? El protocolo
HTTP establece dos mtodos estndar para transferir los datos de un formulario: GET y POST, el cual se escoge con el
atributo method del elemento form. En el Listado 7.20 se utiliz el mtodo GET (lnea 12).
Al texto que aparece despus del carcter signo de pregunta en el URL anterior (marcado en negritas) se le conoce como
query string, y es visible al visitante. Esto se puede probar al correr el programa del Listado 7.20, escribir un par de
valores en los campos de texto y examinar la barra de direcciones del navegador tras presionar el botn de enviar. Incluso,
el visitante puede cambiar los valores en la barra de direcciones y ejecutar de nuevo el programa con ellos; o bien guardar
el URL en sus favoritos.
PHP facilita el trabajo al programador, y cada vez que se llama un script, el intrprete de PHP "parsea" el query string y
extrae cada valor que en l encuentre, y los agrega a un arreglo asociativo superglobal llamado $_GET, de tal forma que el
programador puede acceder a los valores con la expresin:
$field_value = $_GET['field_name'];
donde field_name corresponde al valor del atributo name del campo input, select o textarea definido en el formulario web.
En lo siguiente se explicar paso a paso la lgica del Listado 7.20.
La primera vez que el visitante accede al programa login1.php normalmente no provee un query string, y por ende las
variables $username y $password adquirirn cadenas vacas en las lneas 2 y 3; ya que la funcin isset() retorna true slo
para variables definidas, lo cual no ocurre con las entradas $_GET['username'] y $_GET['password'] en el arreglo asociativo
$_GET. De esta forma, la condicin del if en la lnea 4 se evala como false y hace que el intrprete de PHP imprima el
formulario (lneas 11 a 16), el cual es enviado al navegador.
El navegador presenta el formulario vaco, el cual consta de los siguientes controles: un campo de texto normal con nombre
username (lnea 13), un campo de texto especial para escribir contraseas llamado password (lnea 14), y el botn de enviar
(lnea 15). Supngase que el visitante escribe 'chema' en el campo username, 'semeolvido' en el campo password y presiona
el botn Enviar. Para el navegador este botn es especial, y cuando se activa busca el formulario al cual pertenece (lnea
12), y examinando su atributo action obtiene el programa al que se le debe enviar los valores ingresados por el usuario
(login1.php) y a travs de cul mtodo (get). El navegador recopila los nombres y los valores de cada campo, arma el query
string y lo concatena al URL del programa, lo cual genera el siguiente URL:
http://www.ejemplo.com/path/login1.php?username=chema&password=semeolvido
Seguidamente, el navegador pone este URL en la barra de direcciones y enva el siguiente mensaje de solicitud HTTP al
servidor (los cambios de lnea son significativos):
1. GET /path/login1.php?username=chema&password=semeolvido HTTP/1.1
2. Host: www.ejemplo.com:80
3. User-Agent: Chrome/13
4.
22/09/2015 11:52 a. m.
93 de 99
Como se puede ver, los valores de los campos viajan en la lnea de solicitud (request line) del mensaje de solicitud HTTP,
precedidos por el mtodo de solicitud GET del estndar HTTP. Al recibir este mensaje, el servidor web localiza dentro de su
sitio el recurso /path/login1.php y de acuerdo a su configuracin, la extensin .php le indica que debe invocar al intrprete
de PHP envindole por parmetro el mensaje de solicitud completo, ms otra informacin.
El intrprete de PHP recibe la informacin del servidor web, y la distribuye en los arreglos superglobales $_SERVER, $_ENV,
etc. "Parsea" el query string; llena el arreglo asociativo $_GET e inicia la ejecucin del login1.php del Listado 7.20, pero esta
vez habr una diferencia importante: las entradas $_GET['username'] y $_GET['password'] estn definidas en el arreglo
asociativo $_GET, por lo que las variables $username y $password adquirirn los valores 'chema' y 'semeolvido'
respectivamente en las lneas 2 y 3. La condicin del if esta vez se evaluar como verdadera y se imprimir el texto de
bienvenida, el cual es regresado como resultado al servidor web, quien lo despachar al cliente.
Cuando el intrprete de PHP ejecuta un script, toma las parejas campo=valor del query string y las agrega al arreglo
asociativo $_GET, y las parejas que el navegador enva en el cuerpo del mensaje HTTP, las agrega al arreglo asociativo
$_POST. Como es de notar, ambos mtodos no son excluyentes. El programador debe simplemente tener el cuidado de
utilizar el arreglo asociativo correspondiente al mtodo escogido en el atributo method del elemento form.
A modo de ilustracin supngase que el visitante ingresa los mismos valores: 'chema' en el campo username, 'semeolvido'
en el campo password y presiona el botn Enviar del Listado 7.21. Esta vez el navegador detecta que el mtodo de envo de
datos es POST, y ensambla el siguiente mensaje de solicitud HTTP:
1.
2.
3.
4.
5.
6.
7.
En la mayora de situaciones el mtodo POST es preferido sobre el mtodo GET, no slo porque asegura a la aplicacin web
mayor control sobre los datos ingresados, sino por una razn ms. La cantidad de bytes que se puede escribir en un URL es
bastante limitada, mientras que en el cuerpo del mensaje HTTP puede crecer arbitrariamente. Esto es especialmente
necesario cuando se tienen grandes formularios o donde el usuario puede escribir extensas cantidades de texto en sus
campos.
22/09/2015 11:52 a. m.
94 de 99
para descubrir contraseas o informacin sensible. A esta prctica se le llama inyeccin de cdigo y aunque es bastante
fcil evitar sus efectos nocivos, sigue siendo un tipo de ataque comn ya que es fcil para el programador olvidar defender
su cdigo.
Siempre que el programador va a tomar un valor de los arreglos $_GET y $_POST, debe "esterilizarlo" (sanitize) primero; lo
cual se logra neutralizando el efecto de los caracteres especiales en cada lenguaje. PHP provee varias funciones para
esterilizar cdigo, las cuales se listan en la Tabla 7.4.
Funcin
Descripcin
stripslashes($str)
htmlentities($str)
Retorna un string resultado de reemplazar los caracteres especiales en (X)HTML (<, >, &, ', ")
por sus respectivas entidades (<, >, &, ', ").
strip_tags($str)
Elimina etiquetas (X)HTML que hayan en $str y retorna el resultado en una nueva cadena.
mysql_real_escape_string($str)
Inserta backslahes (\) a los caracteres que tienen significado especial en SQL, como cambios
de lnea y comillas.
Tabla 7.4. Funciones para esterilizar cdigo en PHP
El Listado 7.22 muestra un archivo con funciones de conveniencia que llaman a las listadas en la Tabla 7.4, las cuales se
utilizan en las lneas 2, 3 y 4 del Listado 7.23 para evitar inyeccin de cdigo maligno.
<?php
function sanitize($str)
{
return strip_tags(htmlentities(stripslashes($str)));
}
function sanitize_mysql($str)
{
return sanitize(mysql_real_escape_string($str));
}
function sanitize_trim($str) { return trim(sanitize($str)); }
function sanitize_mysql_trim($str) { return trim(sanitize_mysql($str)); }
?>
Listado 7.22. Funciones de co nveniencia para esterilizar cdigo (X)HTML, PHP y SQL.
1. <body><?php
2.
require_once('sanitize.php');
3.
$username = isset($_POST['username']) ? sanitize_trim($_POST['username']) : '';
4.
$password = isset($_POST['password']) ? sanitize_trim($_POST['password']) : '';
5.
if ( $username != '' && $password != '' )
6.
{
7.
echo "<p>Bienvenido(a) <strong>$username</strong> a nuestro sitio seguro. ";
8.
echo "(No eres <a href=\"login1.php\">$username</a>?).</p>";
9.
}
10.
else
11.
{
12.
echo <<<_EOT
13.
<form method="post" action="login1.php">
14.
<p><label>Usuario: <input type="text" name="username"/></label></p>
15.
<p><label>Contrasea: <input type="password" name="password"/></label></p>
16.
<p><input type="submit" value="Enviar"/></p>
17.
</form>
18. _EOT;
19.
}
20. ?></body>
Listado 7.23. Esterilizacin de cdigo. Correr este ejemplo.
La validacin de datos provistos por el informante es una tarea ms semntica, como por ejemplo, verificar que los nmeros
se encuentren dentro de un rango apropiado, los textos no sean muy cortos o largos, o estn en algn lenguaje natural. En
el Listado 7.23 simplemente se ha discriminado cadenas vacas o constituidas nicamente de espacios en blanco (lnea 5).
22/09/2015 11:52 a. m.
95 de 99
cuando se escribe un formulario, el autor incluye algn texto cercano a cada campo que ayude al informante a saber qu
tipo de informacin debe proveer en l, al cual se le llama rtulo o etiqueta (label). Si tanto el texto como el campo se
escriben dentro de un elemento label, el navegador los asociar semnticamente, de tal forma que cuando el usuario hace
click en el rtulo, el navegador transferir el efecto al campo asociado. Este es el comportamiento natural que el usuario
espera, en especial para checkboxes y radio buttons. Los ejemplos de la Tabla 7.5 incluyen rtulos para ilustrar esta
prctica.
Nombre
Checkbox
Ejemplo
Recordarme
Sexo:
Radio
buttons
Hombre
Mujer
<p>Sexo:
<label><input type="radio" name="sexo" value="1" checked="checked"/>Hombre</label>
<label><input type="radio" name="sexo" value="2"/>Mujer</label>
</p>
Nivel acadmico aprobado:
Combo
box
PHP
Multiple
list
Button
Submit
button
Reset
button
<label>Buscar:
<input type="text" name="buscar" maxlength="255" size="50" value="Escriba su consulta aqu"/>
</label>
22/09/2015 11:52 a. m.
96 de 99
Nombre
Ejemplo
Contrasea:
Password
Text area
<label>
Describa el problema: <br/>
<textarea name="problema" cols="60" rows="6">Escriba los pasos para reproducir el problema</textarea>
</label>
File
select
Hidden
field
A excepcin de las listas (select) y las reas de texto (textarea), la mayora de controles en (X)HTML se escriben con el
elemento input. Su nico atributo obligatorio es type, que indica el tipo de control que se quiere: checkbox, radiobutton, .
Todos los controles comparten el atributo name, cuyo valor es un identificador que no necesariamente debe ser nico en el
documento. Cuando un formulario es aceptado (al presionar el botn "submit"), el navegador ensambla las parejas
campo=valor en el query string a partir de los nombres de los controles y sus respectivos valores. Si un control no tiene
nombre, el navegador simplemente lo ignora. Los dems atributos son dependientes del tipo de control, como se explica en
los siguientes prrafos.
Las casillas de verificacin (checkboxes) permiten al usuario indicar un valor booleano al marcar o no un rectngulo. Se
escriben con la notacin <input type="checkbox" name="checkbox_name" value="yes" checked="checked"/> . Su estado inicial
es desmarcado, a menos de que se provea el atributo checked="checked". Cuando se acepta el formulario, si la casilla de
verificacin est desmarcada, el navegador simplemente no la incluye en el query string. Si la casilla de verificacin est
marcada, se incluye una pareja checkbox_name=on en el query string. El valor "on" lo asume el navegador, pero se puede
reemplazar por un valor ms significativo indicndolo en el atributo value="valor".
Los botones de radio (radio buttons) permiten al informante escoger una nica opcin entre varias disponibles. El autor
debe proveer un elemento <input type="radio" name="nombre_grupo" value="valor" checked="checked"/> por cada opcin.
Si varios botones de radio comparten el mismo nombre, conforman un grupo de botones de radio y slo uno de ellos puede
estar marcado a la vez. Inicialmente todos los botones de radio estn desmarcados a menos de que uno tenga el atributo
checked="checked". Cuando se acepta el formulario (se presiona el botn Submit), si ningn botn de radio en el grupo est
seleccionado, el navegador omite el grupo por completo en el query string; si el botn seleccionado no tiene un valor en el
atributo value, el navegador enva el valor "on" para el grupo, lo cual carece de utilidad para el desarrollador; por eso es
importante proveer un valor adecuado en el atributo value de cada botn de radio, y en tal caso, al aceptar el formulario el
navegador agrega una pareja nombre_grupo=valor, donde valor es el valor del atributo value del botn seleccionado por el
usuario.
Los botones (button) se especifican con <input type="button" value="label del botn"/>. No tienen una accin asociada a
menos de que se les establezca una con JavaScript. Su rtulo se puede cambiar con el atributo value. El botn de enviar
(submit button) se escribe <input type="submit" value="label del botn"/> ejecuta la accin especificada en el atributo
action del formulario (elemento form). Existe una variacin del botn enviar que permite reemplazarlo por una imagen, por
ejemplo: <input type="image" src="enviar.svg" alt="Enviar datos"/>. El botn de limpiar (reset button) se escribe
<input type="reset" value="label del botn"/> y cuando se presiona indica al navegador que regrese todos los controles
del formulario a sus valores originales.
Los campos de texto (text field) son quiz el tipo de control ms usado en el web. Permiten introducir una lnea de texto,
cuya longitud est limitada por el valor del atributo maxlength. El atributo size indica la cantidad de caracteres que tendr
el ancho visible del control, sin embargo, es mejor ajustar el ancho mediante hojas de estilo (CSS). Si se escribe un texto
en el atributo value, se tomar como el valor inicial del campo. En caso de que se quiera delimitar el campo para que
permita nicamente nmeros o valores en cierto formato, se debe emplear JavaScript.
Una variacin del campo de texto son los campos de contrasea (password field) que despliegan asteriscos u otro carcter
especial para encubrir los reales, con el fin de introducir informacin sensible que podra ser vista por una persona ajena al
informante. Tiene otras caractersticas como deshabilitar funciones del portapapeles y disparar el sistema de recuerdo de
contraseas del navegador.
El selector de archivo (file select) permite al visitante adjuntar un archivo cualquiera de su computadora local al
22/09/2015 11:52 a. m.
97 de 99
formulario. Se escribe con el elemento <input type="file" name="nombre_selector"/>. Una vez enviado al servidor, el
nombre del archivo y su contenido se pueden obtener en PHP a travs del arreglo superglobal $_FILES.
El elemento <select name="nombre_lista" size="elementos_visibles" multiple="multiple" value="default_value">...
</select> sirve para construir listas desplegables, listas simples y listas mltiples. Una lista desplegable (combo box)
presenta slo el elemento seleccionado y en caso de que se active el control, una lista emergente muestre todas las
opciones. Las listas desplegables se forman con el atributo size = 1, y aunque permiten seleccin mltiple, no es un
comportamiento natural. Si el valor del atributo size es 2 o ms, el navegador presentar un control de lista simple; y si
el atributo multiple="multiple" est presente, el navegador presentar una lista mltiple donde el usuario podr
seleccionar varios elementos con el ratn mientras mantiene la tecla Ctrl o Command presionada.
Los elementos de la lista se escriben con elementos <option value="valor">Texto</option>. Por defecto el primero ellos
estar seleccionado en caso de que la lista sea desplegable (combo box). Si se quiere preseleccionar otro valor, debe
especificarse con el atributo value del elemento select. Se pueden crear grupos de opciones con el elemento optgroup,
como se ilustra en el Listado 7.24.
Cantn de nacimiento:
Alajuelita
<label>Cantn de nacimiento:<br/>
<select name="canton" size="10">
<optgroup label="San Jos">
<option value="101">San Jos</option>
<option value="102">Escaz</option>
...
<option value="120">Len Corts</option>
</optgroup>
<optgroup label="Alajuela">
<option value="201">Alajuela</option>
<option value="202">San Ramn</option>
...
<option value="215">Guatuso</option>
</optgroup>
...
</select>
</label>
Listado 7.24. Grupos de opciones en un control de lista.
Los campos ocultos (hidden field) son tiles para almacenar valores provenientes del servidor web que no es necesario
mostrar al usuario; pero que pueden ser ledos por cdigo JavaScript, y tambin por cdigo PHP cuando el formulario vuelva
a ser enviado. Se suelen transferir identificadores de usuario o sesin mediante estos campos; los cuales no se deben
asumir seguros, ya que sus valores se pueden descubrir simplemente mirando el cdigo fuente de la pgina web en el
navegador.
El autor puede ajustar la apariencia de todos los controles del formulario mediante hojas de estilos CSS. Es una prctica
comn emplear una tabla dentro del formulario para dar una apariencia ordenada. En tal caso habr que separar los rtulos
de los controles. Por dicha el elemento label tiene el atributo for="id_del_control", que permite conectar el rtulo con el
control mediante el id del control, indiferentemente de dnde se se encuentre dentro del documento web.
22/09/2015 11:52 a. m.
98 de 99
22/09/2015 11:52 a. m.
99 de 99
42.
return 'No utilice caracteres especiales en el nombre\\n';
43.
44.
return '';
45.
}
46.
47.
function validatePassword(value)
48.
{
49.
// Quitar espacios en blanco (trim)
50.
value = value.replace(/^\s+|\s+$/g, '');
51.
52.
// La contrasea es obligatoria
53.
if ( value.length < 8 ) return 'La contrasea debe ser al menos de 8 caracteres\\n';
54.
55.
// Debe tener mayusculas, minusculas y numeros
56.
if ( ! /[a-z]/.test(value) || ! /[A-Z]/.test(value) || ! /[0-9]/.test(value) )
57.
return 'La contrasea debe tener maysculas, minsculas y nmeros';
58.
59.
return '';
60.
}
61.
-->
62.
</script>
63. </body>
Listado 7.25. Validacin de dos campos de un formulario utilizando JavaScript. Co rrer este ejemplo.
La validacin se realiza probando condiciones contra los datos provistos por el usuario. El cdigo del Listado 7.25 emplea
expresiones regulares para hacer ms sencilla la programacin. Una expresin regular en JavaScript se escribe entre dos
caracteres slash (/ /) que no estn seguidos (de lo contrario formaran un comentario). Internamente JavaScript crea un
objeto RegExp que provee el mtodo test(str), el cual recibe una cadena de caracteres, y si logra encontrar la expresin
regular dentro de ella, retorna true. Por su parte, el mtodo str.replace(/exp/g, text) busca todos los textos de str que
cumplen la expresin regulgar exp y los reemplaza por text. El estudio de la nomenclatura de las expresiones regulares se
deja como ejercicio para el lector.
8 Bibliografa
1. [Gars02] GARSHOL, Lars Marius. Definitive XML application development Prentice Hall PTR, United States of America,
2002
2. [Gold99] GOLDFARB, CHARLES Y PRESCOD, PAUL. Manual de XML. Prentice Hall, Madrid, Espaa, 1999.
3. [Holm02] HOLMAN, Ken. Definitive XSLT and XPath Prentice may PTR, United States of America, 2002.
4. [Marc00] MARCHAL, Benot. XML by Example. QUE, United States of America, 2000.
5. [Walm02] WALMSLEY, Priscilla. Definitive XML Schema. Prentice Hall PTR, New Jersey, 2002.
22/09/2015 11:52 a. m.