Cómo obtener una referencia al ámbito global en cualquier entorno JavaScript (HTML, Node.js, Windows Scripting Host…)

El ámbito global de JavaScript es el ámbito superior en el que se definen las variables y que contiene algunas de las funcionalidades globales del entorno de ejecución.

Se trata de un objeto especial que:

  • Siempre está disponible
  • Se llama de manera implícita, es decir, no es necesario mencionar su nombre explícitamente para usar sus métodos o propiedades, al contrario que con cualquier otro objeto.
  • Según indica el estándar ECMAScript, este objeto global no dispone de constructor ni de prototipo y no se puede invocar como una función al igual que el resto de los objetos.

Si en un fragmento de código JavaScript definimos una variable o una función como estas fuera de todo contexto, o sea, para simplificar, sin ser dentro de una función):

var miVar = 0;
function sumar(a, b) {
   return a+b;
}

Lo que estamos haciendo es crear sendos miembros en el objeto global, que es el que constituye dicho ámbito: una variable y una función globales.

Es decir, declarar una variable o una función global implica crear un miembro de este objeto global.

Además, se definen otros ámbitos según en dónde declaremos cada variable, y estos ámbitos se "contienen" unos a otros. Es decir, los ámbitos van en una jerarquía que comienza en el ámbito más restringido y sube hasta llegar al ámbito global. En nuestro ejemplo híper-sencillo tendríamos tan solo dos ámbitos: el global y el de la función:

JavaScript-Ambitos

Desde el ámbito de la función tenemos acceso al ámbito global.

Todo esto de los ámbitos se complica mucho más (tenemos clausuras, por ejemplo). En el estándar podemos leer sobre ello (les llama entornos léxicos) y que nos de vueltas la cabeza.

Como sabemos, aunque nació en los navegadores, JavaScript en la actualidad se utiliza para casi todo, y podemos encontrarlo en casi cualquier entorno imaginable: servidores, dispositivos embebidos, sistemas operativos…

Aunque el estándar ECMAScript describe el objeto global y qué debe contener, no es igual en todos los entornos.

En un navegador el ámbito global lo constituye la ventana en la que se ejecuta el script, y de hecho podemos acceder a él mediante el objeto window. Por ejemplo, a partir del código anterior que definía una variable y una función podríamos escribir:

alert(miVar);
alert(window.miVar);

Y veríamos que son instrucciones equivalentes, ya que al ser una variable global queda definida dentro del ámbito global (es decir, de window en un navegador).

En otros entornos, sin embargo, no disponemos de un objeto window que actúe de ámbito global. Por ejemplo, en Node.js existe un objeto llamado global (o GLOBAL, es un alias) que nos permite acceder al ámbito global. En Windows Scripting Host el objeto global no tiene un nombre definido que lo represente y que nos permita acceder a él directamente… Cada entorno, por tanto, tiene sus particularidades.

La pregunta entonces es: ¿Cómo podemos acceder al ámbito global de JavaScript de manera genérica e independiente del entorno?.

SIGUE LEYENDO para descubrir:

  • Cómo enumerar propiedades de objetos
  • Distintas técnicas de acceso al ámbito global y cuál es la verdaderamente correcta
  • Qué tenemos en el ámbito global ennavegadores, Windows Scripting HOst y NOde.js
  • Por qué en Node.js nos devuelve "cosas extrañas"

Módulo para notificaciones web desde el navegador con HTML5

campusMVP_Notification

Estos días he estado creando un módulo JavaScript para facilitar el uso de las notificaciones del navegador usando la API estándar "Web Notifications" del World Wide Web Consortium (W3C).

La idea es poder mostrar notificaciones nativas al usuario (de las que aparecen al lado del reloj en Windows, por ejemplo) pero desde aplicaciones web. Por ejemplo, cuando llega un nuevo correo (como hace GMail), o cualquier otra circunstancia que necesitemos notificar en segundo plano al usuario, pero desde el navegador.

Actualmente el único navegador que NO las soporta es Internet Explorer / Edge, y no parece que tengan intención de soportarlas tampoco, pero en todos los demás funcionarán sin problemas.

En su día escribí un artículo explicando con detalle cómo utilizarlas "a pelo", sin usar ninguna biblioteca intermedia. Esto es una especie de continuación. Lo que he hecho es crear una biblioteca que, en mi opinión, hace más sencillo el uso de esta característica. Además homogeniza cuestiones como el tiempo de mostrar una notificación o el estado actual de permisos para mostrarlas.

Se trata de un modulo dual y se puede utilizar tanto directamente, incluyéndolo con una etiqueta <script> normal y corriente, como mediante inyección de dependencias con AMD (por ejemplo con Require.js).

He creado un repositorio en GitHub que incluye:

  • Documentación completa del módulo, con explicaciones de las funciones expuestas, su funcionamiento, etc… De momento está solo en inglés, pero entiendo que no debería suponer demasiado problema.
  • El código fuente completo (WebNotifications.js). Incluye comentarios explicativos para entender mejor cómo funciona.
  • La versión minimizada del módulo (WebNotifications.min.js), para usarlo con la mínima carga posible (962 bytes). Incluye un archivo de mapa (WebNotifications.min.js.map) para ayudar a la depuración en producción si fuera necesario.
  • Un archivo de ejemplo de uso (WebNotificationsTest.htm) que implementa todas las funcionalidades para comprobar que funcionan (debe usarse desde un servidor web: en local no funcionará).

¡Espero que lo encuentres útil!

La extraña cabecera "Upgrade-Insecure-Requests" y cómo gestionarla en el servidor

Como todo programador web que se precie, más temprano que tarde acabarás por utilizar el inspector de tráfico de Google Chrome o cualquier otro analizador de protocolos como por ejemplo el magnífico Fiddler. Estas utilidades sirven para inspeccionar todo el tráfico web saliente y poder ver exactamente qué datos se intercambian, poder modificar peticiones y respuestas, etc… lo cual es de gran ayuda para depurar las aplicaciones Web.

Si inspeccionas tráfico generado por Google Chrome verás una cabecera muy rara en casi todas las peticiones dirigidas a través de HTTP:

Upgrade-Insecure-Requests

¿Qué es esta cabecera "Upgrade-Insecure-Requests"?

SIGUE LEYENDO…