Permitir que las aplicaciones web instaladas sean controladores de archivos

Registrar una app como controlador de archivos con el sistema operativo

Ahora que las apps web pueden leer y escribir archivos, el siguiente paso lógico es permitir que los desarrolladores declaren estas mismas apps web como controladores de archivos para los archivos que sus apps pueden crear y procesar. La API de File Handling te permite hacer exactamente eso. Después de registrar una app de editor de texto como controlador de archivos y de instalarla, puedes hacer clic con el botón derecho en un archivo .txt en macOS y seleccionar "Obtener información" para indicarle al SO que siempre debe abrir archivos .txt con esta app de forma predeterminada.

Casos de uso sugeridos para la API de File Handling

Estos son algunos ejemplos de sitios que pueden usar esta API:

  • Aplicaciones de Office, como editores de texto, apps de hojas de cálculo y creadores de presentaciones de diapositivas
  • Editores de gráficos y herramientas de dibujo
  • Herramientas de editores de niveles de videojuegos

Cómo usar la API de File Handling

Mejora progresiva

La API de File Handling per se no se puede reemplazar. Sin embargo, la funcionalidad de abrir archivos con una app web se puede lograr de otras dos maneras:

  • La API de Web Share Target permite a los desarrolladores especificar su app como un destino de uso compartido para que los archivos se puedan abrir desde la hoja compartida del sistema operativo.
  • La API de File System Access se puede integrar con la función de arrastrar y soltar archivos, de modo que los desarrolladores puedan controlar los archivos que se sueltan en la app ya abierta.

Navegadores compatibles

Navegadores compatibles

  • Chrome: 102.
  • Edge: 102.
  • Firefox: No es compatible.
  • Safari: No se admite.

Origen

Detección de atributos

Para verificar si la API de File Handling es compatible, usa lo siguiente:

if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  // The File Handling API is supported.
}

La parte declarativa de la API de File Handling

Como primer paso, las apps web deben describir de forma declarativa en su manifiesto de app web el tipo de archivos que pueden controlar. La API de File Handling extiende el manifiesto de la app web con una nueva propiedad llamada "file_handlers" que acepta un array de controladores de archivos. Un controlador de archivos es un objeto con las siguientes propiedades:

  • Una propiedad "action" que apunta a una URL dentro del alcance de la app como su valor
  • Una propiedad "accept" con un objeto de tipos de MIME como claves y listas de extensiones de archivo como sus valores.
  • Una propiedad "icons" con un array de íconos ImageResource. Algunos sistemas operativos permiten que una asociación de tipo de archivo muestre un ícono que no solo sea el ícono de la aplicación asociada, sino un ícono especial relacionado con el uso de ese tipo de archivo con la aplicación.
  • Es una propiedad "launch_type" que define si se deben abrir varios archivos en un solo cliente o en varios. El valor predeterminado es "single-client". Si el usuario abre varios archivos y el controlador de archivos se anoto con "multiple-clients" como su "launch_type", se producirá más de un inicio de la app y, para cada inicio, el array LaunchParams.files (consulta más abajo) tendrá un solo elemento.

El siguiente ejemplo, que muestra solo el extracto relevante del manifiesto de la app web, debería aclararlo:

{
  "file_handlers": [
    {
      "action": "/open-csv",
      "accept": {
        "text/csv": [".csv"]
      },
      "icons": [
        {
          "src": "csv-icon.png",
          "sizes": "256x256",
          "type": "image/png"
        }
      ],
      "launch_type": "single-client"
    },
    {
      "action": "/open-svg",
      "accept": {
        "image/svg+xml": ".svg"
      },
      "icons": [
        {
          "src": "svg-icon.png",
          "sizes": "256x256",
          "type": "image/png"
        }
      ],
      "launch_type": "single-client"
    },
    {
      "action": "/open-graf",
      "accept": {
        "application/vnd.grafr.graph": [".grafr", ".graf"],
        "application/vnd.alternative-graph-app.graph": ".graph"
      },
      "icons": [
        {
          "src": "graf-icon.png",
          "sizes": "256x256",
          "type": "image/png"
        }
      ],
      "launch_type": "multiple-clients"
    }
  ]
}

Esto es para una aplicación hipotética que controla archivos de valores separados por comas (.csv) en /open-csv, archivos de gráficos vectoriales escalables (.svg) en /open-svg y un formato de archivo Grafr ficticio con cualquiera de .grafr, .graf o .graph como extensión en /open-graf. Los dos primeros se abrirán en un solo cliente y el último en varios clientes si se manejan varios archivos.

La parte imperativa de la API de File Handling

Ahora que la app declaró qué archivos puede controlar en qué URL dentro del alcance en teoría, debe hacer algo de manera imperativa con los archivos entrantes en la práctica. Aquí es donde entra en juego launchQueue. Para acceder a los archivos lanzados, un sitio debe especificar un consumidor para el objeto window.launchQueue. Los lanzamientos se ponen en cola hasta que el consumidor especificado los controla, lo que se invoca exactamente una vez por cada lanzamiento. De esta manera, se controla cada inicio, independientemente de cuándo se especifique el consumidor.

if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
  launchQueue.setConsumer((launchParams) => {
    // Nothing to do when the queue is empty.
    if (!launchParams.files.length) {
      return;
    }
    for (const fileHandle of launchParams.files) {
      // Handle the file.
    }
  });
}

Compatibilidad con Herramientas para desarrolladores

En el momento de escribir este artículo, no hay compatibilidad con DevTools, pero envié una solicitud de función para que se agregue la compatibilidad.

Demostración

Agregué compatibilidad con el manejo de archivos a Excalidraw, una app de dibujo de estilo de caricatura. Para probarla, primero debes instalar Excalidraw. Cuando crees un archivo con él y lo almacenes en algún lugar de tu sistema de archivos, podrás abrirlo con un doble clic o con el botón derecho y, luego, seleccionar "Excalidraw" en el menú contextual. Puedes consultar la implementación en el código fuente.

La ventana del Finder de macOS con un archivo de Excalidraw.
Haz doble clic o clic con el botón derecho en un archivo del explorador de archivos de tu sistema operativo.
Menú contextual que aparece cuando haces clic con el botón derecho en un archivo con el elemento Open with… Excalidraw destacado.
Excalidraw es el controlador de archivos predeterminado para los archivos .excalidraw.

Seguridad

El equipo de Chrome diseñó e implementó la API de File Handling con los principios básicos definidos en Controlling Access to Powerful Web Platform Features, incluidos el control del usuario, la transparencia y la ergonomía.

Permisos, persistencia de permisos y actualizaciones del controlador de archivos

Para garantizar la confianza de los usuarios y la seguridad de sus archivos, cuando la API de File Handling abra un archivo, se mostrará un mensaje de permiso antes de que una AWP pueda ver un archivo. Esta solicitud de permiso se mostrará inmediatamente después de que el usuario seleccione la AWP para abrir un archivo, de modo que el permiso esté estrechamente vinculado a la acción de abrir un archivo con la AWP, lo que lo hace más comprensible y relevante.

Este permiso se mostrará cada vez hasta que el usuario haga clic en Permitir o Bloquear el manejo de archivos del sitio, o bien ignore la solicitud tres veces (después de lo cual Chromium embargará y bloqueará este permiso). El parámetro de configuración seleccionado se conservará cuando se cierre y se vuelva a abrir la AWP.

Cuando se actualice el manifiesto y se detecten cambios en la sección "file_handlers", se restablecerán los permisos.

Existe una gran categoría de vectores de ataque que se abren cuando se permite que los sitios web accedan a los archivos. Estos se describen en el artículo sobre la API de File System Access. La función adicional relacionada con la seguridad que proporciona la API de File Handling sobre la API de File System Access es la capacidad de otorgar acceso a ciertos archivos a través de la IU integrada del sistema operativo, en lugar de a través de un selector de archivos que muestra una aplicación web.

Aún existe el riesgo de que los usuarios otorguen acceso a un archivo a una aplicación web sin querer cuando lo abren. Sin embargo, se entiende que abrir un archivo permite que la aplicación con la que se abre lea o manipule ese archivo. Por lo tanto, la elección explícita de un usuario de abrir un archivo en una aplicación instalada, como a través de un menú contextual "Abrir con…", se puede interpretar como una señal de confianza suficiente en la aplicación.

Desafíos del controlador predeterminado

La excepción a esto es cuando no hay aplicaciones en el sistema host para un tipo de archivo determinado. En este caso, algunos sistemas operativos de host pueden promocionar automáticamente el controlador registrado recientemente al controlador predeterminado para ese tipo de archivo de forma silenciosa y sin intervención del usuario. Esto significa que, si el usuario hace doble clic en un archivo de ese tipo, se abrirá automáticamente en la app web registrada. En esos sistemas operativos de host, cuando el usuario-agente determina que no existe un controlador predeterminado para el tipo de archivo, es posible que se requiera un mensaje de permiso explícito para evitar enviar accidentalmente el contenido de un archivo a una aplicación web sin el consentimiento del usuario.

Control de usuarios

La especificación indica que los navegadores no deben registrar todos los sitios que pueden controlar archivos como un controlador de archivos. En cambio, el registro de control de archivos debe estar restringido después de la instalación y nunca debe ocurrir sin la confirmación explícita del usuario, especialmente si un sitio se convertirá en el controlador predeterminado. En lugar de apropiarse de extensiones existentes, como .json, para las que el usuario probablemente ya tiene un controlador predeterminado registrado, los sitios deberían considerar crear sus propias extensiones.

Transparencia

Todos los sistemas operativos permiten que los usuarios cambien las asociaciones de archivos actuales. Esto está fuera del alcance del navegador.

Comentarios

El equipo de Chrome quiere conocer tus experiencias con la API de File Handling.

Cuéntanos sobre el diseño de la API

¿Hay algo en la API que no funciona como esperabas? ¿O faltan métodos o propiedades que necesitas para implementar tu idea? ¿Tienes alguna pregunta o comentario sobre el modelo de seguridad?

  • Informa un problema de especificación en el repositorio de GitHub correspondiente o agrega tus comentarios a un problema existente.

Denuncia un problema con la implementación

¿Encontraste un error en la implementación de Chrome? ¿O la implementación es diferente de la especificación?

  • Envía un informe de errores a new.crbug.com. Asegúrate de incluir tantos detalles como sea posible, instrucciones simples para reproducirlo y, luego, ingresa UI>Browser>WebAppInstalls>FileHandling en el cuadro Componentes. Glitch es excelente para compartir recreaciones rápidas y fáciles.

Cómo mostrar compatibilidad con la API

¿Piensas usar la API de File Handling? Tu apoyo público ayuda al equipo de Chrome a priorizar las funciones y les muestra a otros proveedores de navegadores lo importante que es admitirlas.

Vínculos útiles

Agradecimientos

Eric Willigers, Jay Harris y Raymes Khoury especificaron la API de File Handling. Joe Medley revisó este artículo.