Tema representativo de entrevista

Entrevista frontend: ¿Cómo soporta Notification.navigate los enlaces profundos (deep links) confiables de notificaciones push?

FrontendIntermedio
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Diseña un flujo desde una notificación push hasta una página de detalle de orden, y explica los límites entre navigate, notificationclick, action.navigate, permisos y reutilización de ventanas.

1. Prompt y alcance

Una notificación Web Push de comercio electrónico debe abrir el detalle de una orden. La aplicación puede estar cerrada, una ventana existente puede estar abierta o el usuario puede activar una acción. Diseña el enlace profundo (deep link) con la opción navigate y cubre el análisis sintáctico de URLs, permisos, fallback de clics, aperturas duplicadas y el ciclo de vida del Service Worker.

2. Lo que el entrevistador está evaluando

  • Saber que NotificationOptions.navigate es una URL de navegación y que Notification.navigate expone su URL absoluta analizada o una cadena vacía.
  • Distinguir la navegación por defecto de la notificación, la navegación de acciones y el manejo de fallback de notificationclick.
  • Manejar permisos, HTTPS, política de mismo origen (same-origin policy), redirecciones abiertas (open redirects), notificaciones duplicadas y reutilización de ventanas existentes.
  • Mantener la recuperación de rutas, la autenticación y la idempotencia en la capa de aplicación en lugar de tratar la navegación del navegador como una autorización.

3. Preguntas para aclarar primero

  1. ¿El código de la página o un Service Worker llama a showNotification?
  2. ¿Se permiten URLs externas y cómo debe reanudarse una página de orden autenticada tras iniciar sesión?
  3. ¿Los clics en el cuerpo y los clics en las acciones deben abrir rutas diferentes o realizar operaciones distintas?
  4. Cuando existe una ventana del mismo origen, ¿el producto debe enfocarla o crear otra ventana?

4. Respuesta de treinta segundos

Bajo HTTPS, haría que el Service Worker cree una notificación persistente cuya URL navigate pase una lista de permitidos (allowlist) del mismo origen. El navegador puede manejar un cuerpo o una acción con una URL de navegación; una acción sin ella recurre a notificationclick, donde enfoco una ventana existente o abro una ruta de recuperación. Los permisos, las URLs inválidas y los fallos de autenticación aún requieren un manejo explícito en la aplicación.

5. Análisis detallado paso a paso

Paso 1: Construir una URL de notificación validada

js
const target = new URL(`/orders/${orderId}`, self.location.origin);

await self.registration.showNotification("Order shipped", {
  body: "View tracking details",
  tag: `order-${orderId}`,
  navigate: target.href,
  data: { orderId },
});

navigate se resuelve con respecto a la URL base utilizada cuando se crea la notificación. Las rutas proporcionadas por el servidor deben pasar verificaciones de mismo origen y de listas de permitidos de rutas; la entrada arbitraria del usuario nunca debe convertirse en un objetivo de redirección.

Paso 2: Separar la navegación del cuerpo y de las acciones

js
await self.registration.showNotification("Order needs confirmation", {
  body: "Choose an action",
  navigate: "/orders/123",
  actions: [
    { action: "open", title: "View order", navigate: "/orders/123" },
    { action: "help", title: "Contact support" },
  ],
});

Cuando se activa una acción, su propio navigate tiene prioridad. Una acción sin esa URL entra en notificationclick, donde se ejecuta el comportamiento específico de la aplicación. Las rutas del cuerpo y de las acciones deben compartir la misma lista de permitidos y las mismas reglas de recuperación de autenticación.

Paso 3: Manejar el fallback de clics y ventanas existentes

js
self.addEventListener("notificationclick", (event) => {
  event.notification.close();
  if (event.action === "help") {
    event.waitUntil(clients.openWindow("/support"));
    return;
  }
  event.waitUntil(clients.matchAll({ type: "window", includeUncontrolled: true })
    .then((windows) => windows[0]?.focus() ?? clients.openWindow("/orders/123")));
});

El código de producción debe verificar la URL de la ventana, esperar el control del Service Worker y pasar un data de confianza en lugar de codificar una orden de forma rígida (hard-coding). Los navegadores pueden reutilizar o crear una ventana de nivel superior, por lo que la recuperación de la aplicación debe admitir ambos resultados.

Paso 4: Permisos, protocolo y seguridad

Las notificaciones requieren el permiso del usuario y las notificaciones persistentes requieren un Service Worker; las APIs dependen de un contexto seguro. El permiso no es una autorización de negocio: la API de órdenes debe autenticar nuevamente después de que se abra la página. Restringe la navegación al mismo origen o a orígenes externos explícitamente confiables para evitar redirecciones abiertas y enlaces de phishing.

Paso 5: Restaurar el estado de forma idempotente

Después de abrir, lee la ruta y data.orderId, muestra un estado de carga, luego obtén la orden y verifica la identidad. Las notificaciones con el mismo tag deben fusionarse o actualizarse según la política del producto. Los cambios de ruta, la restauración del foco y la analítica deben ser idempotentes para que un solo clic no pueda crear solicitudes o transiciones de estado duplicadas.

6. Respuesta modelo de alta calidad

Haría que el Service Worker cree únicamente URLs navigate del mismo origen que estén en la lista de permitidos y asigne un tag estable. El clic en el cuerpo sigue la navegación del navegador, mientras que la URL de una acción tiene prioridad; una acción sin ella usa notificationclick para enfocar una ventana existente o abrir un fallback. La página se autentica nuevamente, lee el parámetro de la orden y restaura el estado de forma idempotente. Los permisos, HTTPS, las redirecciones abiertas y las URLs externas son comprobaciones independientes; la navegación por notificación nunca es una autorización.

7. Errores comunes

  • Colocar la entrada del usuario directamente en navigate → redirección abierta → aplicar listas de permitidos de mismo origen y de rutas.
  • Asumir que cada clic llega a código personalizado → la navegación del cuerpo puede ser manejada por el navegador → depender de notificationclick solo para acciones sin una URL.
  • Tratar el permiso de notificación como autorización de la orden → exposición de datos → autenticar nuevamente en la página y en la API.
  • Llamar siempre a openWindow → ventanas y solicitudes duplicadas → hacer coincidir ventanas del mismo origen y hacer que la recuperación sea idempotente.
  • Ignorar el ciclo de vida del Service Worker → el trabajo asíncrono se interrumpe → mantener las promesas de finalización dentro de event.waitUntil.

8. Preguntas de seguimiento

Pregunta de seguimiento 1: ¿Qué devuelve Notification.navigate?

Es una cadena de solo lectura que contiene la URL absoluta de navegación serializada de la notificación, o una cadena vacía cuando no se configuró ninguna URL válida.

Pregunta de seguimiento 2: ¿Qué sucede cuando una acción no tiene navigate?

La acción no navega automáticamente. Su activación puede ser manejada por notificationclick en el Service Worker.

Pregunta de seguimiento 3: ¿Por qué autenticar nuevamente en la página?

La URL y data son sugerencias de navegación, no una autorización de identidad o recursos. La API de órdenes debe verificar nuevamente la sesión actual y los permisos del lado del servidor.

Pregunta de seguimiento 4: ¿Cómo pruebas el comportamiento entre ventanas (cross-window)?

Cubre escenarios sin ventana, con una ventana existente del mismo origen, con una ventana no controlada, clics en el cuerpo y en acciones, permiso denegado y URLs inválidas; verifica que la recuperación de la aplicación realice solo una solicitud.

Fuentes públicas

Preguntas relacionadas