File Web Share Target

J'ai souvent dit que pour que les applications Web soient concurrentielles dans le monde des applications, elles doivent être intégrées à tous les endroits que les utilisateurs attendent des applications. La communication inter-applications est l'un des principaux éléments manquants de la plate-forme Web, et l'une des dernières fonctionnalités manquantes est le partage au niveau natif: les applications Web doivent pouvoir accéder à data out of their silo et à d'autres sites Web et applications; ils doivent également pouvoir recevoir les données d'autres applications et sites natifs.

L'API cible de partage de fichiers est le changeur de jeu d'une API qui se trouve maintenant dans Chrome Canary. L'API étend Web Share Target API permettre aux applications et aux sites de partager des liens simples et du texte avec des sites Web en les intégrant à la fonctionnalité de partage de systèmes.

Ce blog de fichiers très statique utilise l'API cible de partage Web afin que je puisse rapidement share links qui me share links intéressant, depuis n'importe quelle application Android et depuis la semaine dernière, I enabled the File Share Target API so that I can upload images to my blog directly from the Camera app on Android . Cet article traite de la façon dont je l’ai fait (et j’ai volé du code à Jake Archibald - il a corrigé beaucoup de bugs pour une intégration qu’ils font dans squoosh.app .)

File Share Target API est une API très nouvelle en ce sens qu’elle est totalement progressive. Si votre application peut gérer les demandes de formulaire POST , vous pouvez facilement l'intégrer à cette API. Le flux de base est le suivant: lorsque l'utilisateur choisit votre application dans le sélecteur natif, Chrome envoie une demande de formulaire POST à votre serveur. Il vous POST de ce que vous en ferez (traitement dans un agent de maintenance ou sur le serveur).

Pour prendre en charge le partage de fichiers dans votre application Web, vous devez effectuer deux tâches:

  1. Déclarez la prise en charge du partage de fichiers via le fichier manifeste,
  2. POST demande de formulaire POST dans votre POST de service.

Le manifeste indique au système hôte comment le partage doit être mappé de l'application hôte vers l'application Web. Dans le manifeste ci-dessous, il est essentiellement indiqué "Lorsqu'un utilisateur partage un fichier de type" image / * ", créez une demande de formulaire POST pour" / share / image / "et nommez le" fichier de données "".

  • manifest.json *
{
  "name": "Blog: Share Image",
  "short_name": "Blog: Share Image",
  "start_url": "/share/image/",
  "theme_color": "#000000",
  "background_color": "#000000",
  "icons": [ {
      "sizes": "192x192",
      "src": "/images/me.png",
      "type": "image/png"
  }],
  "share_target": {
    "action": "/share/image/",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "files": [
        {
          "name": "file",
          "accept": ["image/*"]
        }
      ]
    }
  },
  "display": "standalone",
  "scope": "/share/"
}

Une fois que l'utilisateur a partagé votre application Web, Chrome envoie la demande Web à votre site avec les données du fichier comme charge utile.

Il est recommandé de gérer la demande POST dans votre centre de services afin que 1) la demande soit rapide, 2) résiliente face à la non disponibilité du réseau. Vous pouvez le faire comme suit:

  • serviceworker.js * - demo
onfetch = async (event) => {
  if (event.request.method !== 'POST') return;
  if (event.request.url.startsWith('https://paul.kinlan.me/share/image/') === false) return;

  /* This is to fix the issue Jake found */
  event.respondWith(Response.redirect('/share/image/'));
  
  event.waitUntil(async function () {
    const data = await event.request.formData();
    const client = await self.clients.get(event.resultingClientId || event.clientId);
    // Get the data from the named element 'file'
    const file = data.get('file');

    console.log('file', file);
    client.postMessage({ file, action: 'load-image' });
  }());
};

Deux choses intéressantes se passent ci-dessus, qui peuvent rapidement être résumées comme suit:

  • Rendez l'interface utilisateur à la suite de la demande POST en effectuant une redirection.
  • Lire les données qui sont soumises via le formulaire via event.request.formData()
  • Envoyer les données à la fenêtre ouverte (ce sera l'interface utilisateur vers laquelle nous avons redirigé l'utilisateur dans le premier point).

C’est entièrement à vous de décider de ce que vous faites des données qui ont été envoyées à votre technicien, mais dans le cas de mon application, je devais les afficher directement dans l’interface utilisateur, de sorte que je devais trouver la fenêtre que l'utilisateur utilisait et postMessage les données là-bas.

  • index.html * - demo
navigator.serviceWorker.onmessage = (event) => {
  console.log(event);
  imageBlob = event.data.file;
  // Update the UI with the data that has been shared to it.
  imageShare.src = URL.createObjectURL(imageBlob);
};

Et c'est à peu près tout. Si vous disposez déjà d'un point de terminaison API pour vos formulaires Web, il s'agit d'un ajout simple, mais puissant, que vous pouvez apporter à votre site.

La primitive de plate-forme incroyablement puissante de l'API Web Share Target supprime un autre obstacle que les applications Web rencontraient sur leurs plates-formes hôtes.

About Me: Paul Kinlan

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.