Interagir avec des appareils NFC sur Chrome pour Android

Il est désormais possible de lire et d'écrire dans des tags NFC.

François Beaufort
François Beaufort

Qu'est-ce que le Web NFC ?

NFC signifie "communication en champ proche", une technologie sans fil de courte portée fonctionnant à 13,56 MHz, qui permet la communication entre des appareils à une distance inférieure à 10 cm et un débit de transmission allant jusqu'à 424 kbit/s.

Le NFC Web permet aux sites de lire et d'écrire dans des tags NFC lorsqu'ils se trouvent à proximité de l'appareil de l'utilisateur (généralement entre 5 et 10 cm ou 2 à 4 pouces). Le champ d'application actuel est limité au format NDEF (NFC Data Exchange Format), un format de message binaire léger qui fonctionne avec différents formats de tag.

Téléphone qui active un tag NFC pour échanger des données
Schéma d'une opération NFC

Cas d'utilisation suggérés

Le NFC Web est limité au NDEF, car les propriétés de sécurité de la lecture et de l'écriture des données NDEF sont plus facilement quantifiables. Les opérations d'E/S de bas niveau (par exemple, ISO-DEP, NFC-A/B, NFC-F), le mode de communication peer-to-peer et l'émulation de carte basée sur l'hôte (HCE) ne sont pas acceptées.

Voici quelques exemples de sites susceptibles d'utiliser la technologie Web NFC:

  • Les musées et galeries d'art peuvent afficher des informations supplémentaires sur un écran lorsque l'utilisateur met son appareil en contact avec une carte NFC à proximité de l'exposition.
  • Les sites de gestion de l'inventaire peuvent lire ou écrire des données dans le tag NFC d'un conteneur pour mettre à jour les informations sur son contenu.
  • Les sites de conférence peuvent l'utiliser pour scanner les badges NFC pendant l'événement et s'assurer qu'ils sont verrouillés pour éviter d'autres modifications des informations qui y sont inscrites.
  • Les sites peuvent l'utiliser pour partager les secrets initiaux nécessaires à des scénarios de provisionnement d'appareils ou de services, ainsi que pour déployer des données de configuration en mode opérationnel.
Scanner plusieurs tags NFC par téléphone
Illustration de la gestion de l'inventaire NFC

État actuel

Step État
1. Créer une vidéo explicative Fin
2. Créer un brouillon initial de la spécification Fin
3. Recueillir des commentaires et itérer sur la conception Fin
4. Phase d'évaluation Fin
5. Lancement Fin

Utiliser Web NFC

Détection de fonctionnalités

La détection des caractéristiques du matériel est différente de ce à quoi vous êtes probablement habitué. La présence de NDEFReader vous indique que le navigateur est compatible avec le NFC Web, mais pas si le matériel requis est présent. En particulier, si le matériel est manquant, la promesse renvoyée par certains appels sera rejetée. Je vous fournirai des détails lorsque je décrirai NDEFReader.

if ('NDEFReader' in window) { /* Scan and write NFC tags */ }

Terminologie

Un tag NFC est un appareil NFC passif, c'est-à-dire qu'il est alimenté par induction magnétique lorsqu'un appareil NFC actif (comme un téléphone) se trouve à proximité. Les tags NFC sont disponibles sous de nombreuses formes et de nombreux modes, tels que des autocollants, des cartes de crédit, des poignets de poignet, etc.

Photo d'un tag NFC transparent
Tag NFC transparent

L'objet NDEFReader est le point d'entrée dans le NFC Web. Il expose une fonctionnalité permettant de préparer les actions de lecture et/ou d'écriture exécutées lorsqu'une balise NDEF se trouve à proximité. Le NDEF dans NDEFReader correspond au format d'échange de données NFC, un format de message binaire léger standardisé par le Forum NFC.

L'objet NDEFReader permet d'agir sur les messages NDEF entrants à partir de tags NFC et d'écrire des messages NDEF dans des tags NFC à proximité.

Un tag NFC compatible avec le NDEF est semblable à un post-it. Tout le monde peut le lire et, sauf s'il est en lecture seule, tout le monde peut y écrire. Il contient un seul message NDEF qui encapsule un ou plusieurs enregistrements NDEF. Chaque enregistrement NDEF est une structure binaire contenant une charge utile de données et les informations de type associées. Le NFC Web est compatible avec les types d'enregistrements standardisés NFC Forum suivants: vide, texte, URL, poster intelligent, type MIME, URL absolue, type externe, inconnu et type local.

Schéma d'un message NDEF
Diagramme d'un message NDEF

Scanner des tags NFC

Pour scanner des tags NFC, instanciez d'abord un nouvel objet NDEFReader. L'appel de scan() renvoie une promesse. L'utilisateur peut être invité si l'accès n'a pas été précédemment accordé. La promesse sera résolue si toutes les conditions suivantes sont remplies:

  • Il n'était appelé qu'en réponse à un geste de l'utilisateur, tel qu'un geste tactile ou un clic de souris.
  • L'utilisateur a autorisé le site Web à interagir avec des appareils NFC.
  • Le téléphone de l'utilisateur est compatible NFC.
  • L'utilisateur a activé la technologie NFC sur son téléphone.

Une fois la promesse résolue, les messages NDEF entrants sont disponibles en vous abonnant aux événements reading via un écouteur d'événements. Vous devez également vous abonner aux événements readingerror pour être averti lorsque des tags NFC incompatibles se trouvent à proximité.

const ndef = new NDEFReader();
ndef.scan().then(() => {
  console.log("Scan started successfully.");
  ndef.onreadingerror = () => {
    console.log("Cannot read data from the NFC tag. Try another one?");
  };
  ndef.onreading = event => {
    console.log("NDEF message read.");
  };
}).catch(error => {
  console.log(`Error! Scan failed to start: ${error}.`);
});

Lorsqu'un tag NFC se trouve à proximité, un événement NDEFReadingEvent est déclenché. Il contient deux propriétés qui lui sont propres:

  • serialNumber représente le numéro de série de l'appareil (par exemple, 00-11-22-33-44-55-66) ou une chaîne vide si aucun n'est disponible.
  • message représente le message NDEF stocké dans le tag NFC.

Pour lire le contenu du message NDEF, passez en boucle message.records et traitez les membres data de manière appropriée en fonction de leur recordType. Le membre data est exposé en tant que DataView, car il permet de gérer les cas où les données sont encodées au format UTF-16.

ndef.onreading = event => {
  const message = event.message;
  for (const record of message.records) {
    console.log("Record type:  " + record.recordType);
    console.log("MIME type:    " + record.mediaType);
    console.log("Record id:    " + record.id);
    switch (record.recordType) {
      case "text":
        // TODO: Read text record with record data, lang, and encoding.
        break;
      case "url":
        // TODO: Read URL record with record data.
        break;
      default:
        // TODO: Handle other records with record data.
    }
  }
};

Écrire des tags NFC

Pour écrire des tags NFC, instanciez d'abord un nouvel objet NDEFReader. Appeler write() renvoie une promesse. L'utilisateur peut être invité si l'accès n'a pas été précédemment accordé. À ce stade, un message NDEF est "préparé" et la promesse se résout si les conditions suivantes sont toutes remplies:

  • Il n'était appelé qu'en réponse à un geste de l'utilisateur, tel qu'un geste tactile ou un clic de souris.
  • L'utilisateur a autorisé le site Web à interagir avec des appareils NFC.
  • Le téléphone de l'utilisateur est compatible NFC.
  • L'utilisateur a activé la technologie NFC sur son téléphone.
  • L'utilisateur a appuyé sur un tag NFC et un message NDEF a bien été écrit.

Pour écrire du texte dans un tag NFC, transmettez une chaîne à la méthode write().

const ndef = new NDEFReader();
ndef.write(
  "Hello World"
).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Pour écrire un enregistrement d'URL dans un tag NFC, transmettez un dictionnaire représentant un message NDEF à write(). Dans l'exemple ci-dessous, le message NDEF est un dictionnaire doté d'une clé records. Sa valeur est un tableau d'enregistrements. Dans ce cas, un enregistrement d'URL défini en tant qu'objet avec une clé recordType définie sur "url" et une clé data définie sur la chaîne d'URL.

const ndef = new NDEFReader();
ndef.write({
  records: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }]
}).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Il est également possible d'écrire plusieurs enregistrements sur une balise NFC.

const ndef = new NDEFReader();
ndef.write({ records: [
    { recordType: "url", data: "https://w3c.github.io/web-nfc/" },
    { recordType: "url", data: "https://web.dev/nfc/" }
]}).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Si le tag NFC contient un message NDEF qui n'est pas destiné à être écrasé, définissez la propriété overwrite sur false dans les options transmises à la méthode write(). Dans ce cas, la promesse renvoyée sera rejetée si un message NDEF est déjà stocké dans le tag NFC.

const ndef = new NDEFReader();
ndef.write("Writing data on an empty NFC tag is fun!", { overwrite: false })
.then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

Définir les tags NFC en lecture seule

Pour éviter que des utilisateurs malveillants n'écrasent le contenu d'un tag NFC, il est possible de rendre les tags NFC en lecture seule de manière permanente. Cette opération est un processus à sens unique et ne peut pas être annulée. Une fois qu'un tag NFC est passé en lecture seule, il ne peut plus être écrit.

Pour que les tags NFC soient en lecture seule, instanciez d'abord un nouvel objet NDEFReader. Appeler makeReadOnly() renvoie une promesse. L'utilisateur peut être invité si l'accès n'a pas été précédemment accordé. La promesse sera résolue si les conditions suivantes sont toutes remplies:

  • Il n'était appelé qu'en réponse à un geste de l'utilisateur, tel qu'un geste tactile ou un clic de souris.
  • L'utilisateur a autorisé le site Web à interagir avec des appareils NFC.
  • Le téléphone de l'utilisateur est compatible NFC.
  • L'utilisateur a activé la technologie NFC sur son téléphone.
  • L'utilisateur a appuyé sur un tag NFC, qui est passé en lecture seule.
const ndef = new NDEFReader();
ndef.makeReadOnly()
.then(() => {
  console.log("NFC tag has been made permanently read-only.");
}).catch(error => {
  console.log(`Operation failed: ${error}`);
});

Voici comment définir un tag NFC en lecture seule en lecture seule après avoir écrit sur celui-ci.

const ndef = new NDEFReader();
try {
  await ndef.write("Hello world");
  console.log("Message written.");
  await ndef.makeReadOnly();
  console.log("NFC tag has been made permanently read-only after writing to it.");
} catch (error) {
  console.log(`Operation failed: ${error}`);
}

Comme makeReadOnly() est disponible sur Android dans Chrome 100 ou version ultérieure, vérifiez si cette fonctionnalité est compatible avec les éléments suivants:

if ("NDEFReader" in window && "makeReadOnly" in NDEFReader.prototype) {
  // makeReadOnly() is supported.
}

Sécurité et autorisations

L'équipe Chrome a conçu et mis en œuvre la technologie Web NFC en suivant les principes fondamentaux définis dans l'article Contrôler l'accès aux fonctionnalités puissantes de la plate-forme Web, comme le contrôle utilisateur, la transparence et l'ergonomie.

Étant donné que la technologie NFC étend le domaine des informations potentiellement disponibles pour les sites Web malveillants, sa disponibilité est limitée afin de maximiser la visibilité et le contrôle des utilisateurs vis-à-vis de la technologie NFC.

Capture d'écran d'une invite NFC Web sur un site Web
Requête Web NFC à l'utilisateur

Le NFC Web n'est disponible que pour les frames de niveau supérieur et les contextes de navigation sécurisés (HTTPS uniquement). Les origines doivent d'abord demander l'autorisation "nfc" lors de la gestion d'un geste de l'utilisateur (par exemple, un clic sur un bouton). Les méthodes NDEFReader scan(), write() et makeReadOnly() déclenchent une invite utilisateur si l'accès n'a pas été précédemment accordé.

  document.querySelector("#scanButton").onclick = async () => {
    const ndef = new NDEFReader();
    // Prompt user to allow website to interact with NFC devices.
    await ndef.scan();
    ndef.onreading = event => {
      // TODO: Handle incoming NDEF messages.
    };
  };

La combinaison d'une invite d'autorisation déclenchée par l'utilisateur et d'un mouvement physique réel consistant à placer l'appareil sur un tag NFC cible reflète le schéma de sélection trouvé dans les autres API d'accès aux fichiers et aux appareils.

Pour que vous puissiez effectuer une numérisation ou une écriture, la page Web doit être visible lorsque l'utilisateur touche un tag NFC avec son appareil. Le navigateur utilise le retour haptique pour indiquer qu'un utilisateur appuie dessus. L'accès au signal radio NFC est bloqué si l'écran est éteint ou si l'appareil est verrouillé. Pour les pages Web non visibles, la réception et le transfert de contenu NFC sont suspendus et réactivés lorsqu'une page Web redevient visible.

Grâce à l'API Page Visibility, il est possible de suivre les modifications de visibilité des documents.

document.onvisibilitychange = event => {
  if (document.hidden) {
    // All NFC operations are automatically suspended when document is hidden.
  } else {
    // All NFC operations are resumed, if needed.
  }
};

Livre de recettes

Voici quelques exemples de code pour vous aider à démarrer.

Vérifier les autorisations

L'API Permissions permet de vérifier si l'autorisation "nfc" a été accordée. Cet exemple montre comment scanner des tags NFC sans interaction de l'utilisateur si l'accès a déjà été accordé ou comment afficher un bouton dans le cas contraire. Notez que le même mécanisme fonctionne pour l'écriture de tags NFC, car il utilise la même autorisation en arrière-plan.

const ndef = new NDEFReader();

async function startScanning() {
  await ndef.scan();
  ndef.onreading = event => {
    /* handle NDEF messages */
  };
}

const nfcPermissionStatus = await navigator.permissions.query({ name: "nfc" });
if (nfcPermissionStatus.state === "granted") {
  // NFC access was previously granted, so we can start NFC scanning now.
  startScanning();
} else {
  // Show a "scan" button.
  document.querySelector("#scanButton").style.display = "block";
  document.querySelector("#scanButton").onclick = event => {
    // Prompt user to allow UA to send and receive info when they tap NFC devices.
    startScanning();
  };
}

Annuler les opérations NFC

L'utilisation de la primitive AbortController permet d'annuler facilement les opérations NFC. L'exemple ci-dessous vous montre comment transmettre le signal d'un AbortController via les options des méthodes NDEFReader scan(), makeReadOnly() et write() et comment annuler les deux opérations NFC en même temps.

const abortController = new AbortController();
abortController.signal.onabort = event => {
  // All NFC operations have been aborted.
};

const ndef = new NDEFReader();
await ndef.scan({ signal: abortController.signal });

await ndef.write("Hello world", { signal: abortController.signal });
await ndef.makeReadOnly({ signal: abortController.signal });

document.querySelector("#abortButton").onclick = event => {
  abortController.abort();
};

Lecture après écriture

L'utilisation de write(), puis de scan() avec la primitive AbortController permet de lire un tag NFC après y avoir écrit un message. L'exemple ci-dessous vous montre comment écrire un message sur un tag NFC et lire le nouveau message dans ce tag. La recherche s'arrête au bout de trois secondes.

// Waiting for user to tap NFC tag to write to it...
const ndef = new NDEFReader();
await ndef.write("Hello world");
// Success! Message has been written.

// Now scanning for 3 seconds...
const abortController = new AbortController();
await ndef.scan({ signal: abortController.signal });
const message = await new Promise((resolve) => {
  ndef.onreading = (event) => resolve(event.message);
});
// Success! Message has been read.

await new Promise((r) => setTimeout(r, 3000));
abortController.abort();
// Scanning is now stopped.

Lire et écrire un enregistrement texte

L'enregistrement texte data peut être décodé avec un TextDecoder instancié avec la propriété d'enregistrement encoding. Notez que la langue de l'enregistrement de texte est disponible via sa propriété lang.

function readTextRecord(record) {
  console.assert(record.recordType === "text");
  const textDecoder = new TextDecoder(record.encoding);
  console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
}

Pour écrire un enregistrement de texte simple, transmettez une chaîne à la méthode write() de NDEFReader.

const ndef = new NDEFReader();
await ndef.write("Hello World");

Les enregistrements texte sont au format UTF-8 par défaut et supposent la langue du document actuel, mais les deux propriétés (encoding et lang) peuvent être spécifiées à l'aide de la syntaxe complète pour créer un enregistrement NDEF personnalisé.

function a2utf16(string) {
  let result = new Uint16Array(string.length);
  for (let i = 0; i < string.length; i++) {
    result[i] = string.codePointAt(i);
  }
  return result;
}

const textRecord = {
  recordType: "text",
  lang: "fr",
  encoding: "utf-16",
  data: a2utf16("Bonjour, François !")
};

const ndef = new NDEFReader();
await ndef.write({ records: [textRecord] });

Lire et écrire un enregistrement d'URL

Utilisez TextDecoder pour décoder le data de l'enregistrement.

function readUrlRecord(record) {
  console.assert(record.recordType === "url");
  const textDecoder = new TextDecoder();
  console.log(`URL: ${textDecoder.decode(record.data)}`);
}

Pour écrire un enregistrement d'URL, transmettez un dictionnaire de messages NDEF à la méthode write() NDEFReader. L'enregistrement d'URL contenu dans le message NDEF est défini comme un objet avec une clé recordType définie sur "url" et une clé data définie sur la chaîne d'URL.

const urlRecord = {
  recordType: "url",
  data:"https://w3c.github.io/web-nfc/"
};

const ndef = new NDEFReader();
await ndef.write({ records: [urlRecord] });

Lire et écrire un enregistrement de type MIME

La propriété mediaType d'un enregistrement de type MIME représente le type MIME de la charge utile de l'enregistrement NDEF, ce qui permet de décoder correctement data. Par exemple, utilisez JSON.parse pour décoder du texte JSON et un élément Image pour décoder les données d'image.

function readMimeRecord(record) {
  console.assert(record.recordType === "mime");
  if (record.mediaType === "application/json") {
    const textDecoder = new TextDecoder();
    console.log(`JSON: ${JSON.parse(decoder.decode(record.data))}`);
  }
  else if (record.mediaType.startsWith('image/')) {
    const blob = new Blob([record.data], { type: record.mediaType });
    const img = new Image();
    img.src = URL.createObjectURL(blob);
    document.body.appendChild(img);
  }
  else {
    // TODO: Handle other MIME types.
  }
}

Pour écrire un enregistrement de type MIME, transmettez un dictionnaire de messages NDEF à la méthode write() NDEFReader. L'enregistrement de type MIME contenu dans le message NDEF est défini comme un objet avec une clé recordType définie sur "mime", une clé mediaType définie sur le type MIME réel du contenu et une clé data définie sur un objet qui peut être une ArrayBuffer ou fournit une vue sur un ArrayBuffer (par exemple, Uint8Array ou DataView).

const encoder = new TextEncoder();
const data = {
  firstname: "François",
  lastname: "Beaufort"
};
const jsonRecord = {
  recordType: "mime",
  mediaType: "application/json",
  data: encoder.encode(JSON.stringify(data))
};

const imageRecord = {
  recordType: "mime",
  mediaType: "image/png",
  data: await (await fetch("icon1.png")).arrayBuffer()
};

const ndef = new NDEFReader();
await ndef.write({ records: [jsonRecord, imageRecord] });

Lire et écrire un enregistrement d'URL absolue

L'enregistrement d'URL absolue data peut être décodé avec un simple TextDecoder.

function readAbsoluteUrlRecord(record) {
  console.assert(record.recordType === "absolute-url");
  const textDecoder = new TextDecoder();
  console.log(`Absolute URL: ${textDecoder.decode(record.data)}`);
}

Pour écrire un enregistrement d'URL absolu, transmettez un dictionnaire de messages NDEF à la méthode write() NDEFReader. L'enregistrement d'URL absolue contenu dans le message NDEF est défini comme un objet avec une clé recordType définie sur "absolute-url" et une clé data définie sur la chaîne d'URL.

const absoluteUrlRecord = {
  recordType: "absolute-url",
  data:"https://w3c.github.io/web-nfc/"
};

const ndef = new NDEFReader();
await ndef.write({ records: [absoluteUrlRecord] });

Lire et créer un poster intelligent

Un enregistrement poster intelligent (utilisé dans les publicités de magazines, les dépliants, les panneaux d'affichage, etc.) décrit un contenu Web comme un enregistrement NDEF qui contient un message NDEF en tant que charge utile. Appelez record.toRecords() pour transformer data en une liste d'enregistrements contenu dans l'enregistrement de l'auteur intelligent. Il doit comporter un enregistrement d'URL, un enregistrement texte pour le titre, un enregistrement de type MIME pour l'image et certains enregistrements de types locaux personnalisés tels que ":t", ":act" et ":s" respectivement pour le type, l'action et la taille de l'enregistrement du posteur intelligent.

Les enregistrements de type local ne sont uniques que dans le contexte local de l'enregistrement NDEF qui les contient. Utilisez-les lorsque la signification des types n'a pas d'importance en dehors du contexte local de l'enregistrement conteneur et lorsque l'utilisation du stockage est une contrainte stricte. Les noms d'enregistrements de type local commencent toujours par : dans le NFC Web (par exemple, ":t", ":s", ":act"). Cela permet de différencier un enregistrement texte d'un enregistrement texte de type local, par exemple.

function readSmartPosterRecord(smartPosterRecord) {
  console.assert(record.recordType === "smart-poster");
  let action, text, url;

  for (const record of smartPosterRecord.toRecords()) {
    if (record.recordType == "text") {
      const decoder = new TextDecoder(record.encoding);
      text = decoder.decode(record.data);
    } else if (record.recordType == "url") {
      const decoder = new TextDecoder();
      url = decoder.decode(record.data);
    } else if (record.recordType == ":act") {
      action = record.data.getUint8(0);
    } else {
      // TODO: Handle other type of records such as `:t`, `:s`.
    }
  }

  switch (action) {
    case 0:
      // Do the action
      break;
    case 1:
      // Save for later
      break;
    case 2:
      // Open for editing
      break;
  }
}

Pour écrire un enregistrement poster intelligent, transmettez un message NDEF à la méthode write() NDEFReader. L'enregistrement du poster intelligent contenu dans le message NDEF est défini comme un objet avec une clé recordType définie sur "smart-poster" et une clé data définie sur un objet qui représente (à nouveau) un message NDEF contenu dans l'enregistrement de poster intelligent.

const encoder = new TextEncoder();
const smartPosterRecord = {
  recordType: "smart-poster",
  data: {
    records: [
      {
        recordType: "url", // URL record for smart poster content
        data: "https://my.org/content/19911"
      },
      {
        recordType: "text", // title record for smart poster content
        data: "Funny dance"
      },
      {
        recordType: ":t", // type record, a local type to smart poster
        data: encoder.encode("image/gif") // MIME type of smart poster content
      },
      {
        recordType: ":s", // size record, a local type to smart poster
        data: new Uint32Array([4096]) // byte size of smart poster content
      },
      {
        recordType: ":act", // action record, a local type to smart poster
        // do the action, in this case open in the browser
        data: new Uint8Array([0])
      },
      {
        recordType: "mime", // icon record, a MIME type record
        mediaType: "image/png",
        data: await (await fetch("icon1.png")).arrayBuffer()
      },
      {
        recordType: "mime", // another icon record
        mediaType: "image/jpg",
        data: await (await fetch("icon2.jpg")).arrayBuffer()
      }
    ]
  }
};

const ndef = new NDEFReader();
await ndef.write({ records: [smartPosterRecord] });

Lire et écrire un enregistrement de type externe

Pour créer des enregistrements définis par l'application, utilisez des enregistrements de type externe. Ceux-ci peuvent contenir un message NDEF en tant que charge utile accessible avec toRecords(). Leur nom contient le nom de domaine de l'organisation émettrice, un signe deux-points et un nom de type d'au moins un caractère, par exemple "example.com:foo".

function readExternalTypeRecord(externalTypeRecord) {
  for (const record of externalTypeRecord.toRecords()) {
    if (record.recordType == "text") {
      const decoder = new TextDecoder(record.encoding);
      console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
    } else if (record.recordType == "url") {
      const decoder = new TextDecoder();
      console.log(`URL: ${decoder.decode(record.data)}`);
    } else {
      // TODO: Handle other type of records.
    }
  }
}

Pour écrire un enregistrement de type externe, transmettez un dictionnaire de messages NDEF à la méthode write() NDEFReader. L'enregistrement de type externe contenu dans le message NDEF est défini comme un objet avec une clé recordType définie sur le nom du type externe et une clé data définie sur un objet représentant un message NDEF contenu dans l'enregistrement de type externe. Notez que la clé data peut également être une ArrayBuffer ou fournir une vue sur un ArrayBuffer (par exemple, Uint8Array ou DataView).

const externalTypeRecord = {
  recordType: "example.game:a",
  data: {
    records: [
      {
        recordType: "url",
        data: "https://example.game/42"
      },
      {
        recordType: "text",
        data: "Game context given here"
      },
      {
        recordType: "mime",
        mediaType: "image/png",
        data: await (await fetch("image.png")).arrayBuffer()
      }
    ]
  }
};

const ndef = new NDEFReader();
ndef.write({ records: [externalTypeRecord] });

Lire et écrire un enregistrement vide

Un enregistrement vide n'a pas de charge utile.

Pour écrire un enregistrement vide, transmettez un dictionnaire de messages NDEF à la méthode write() NDEFReader. L'enregistrement vide contenu dans le message NDEF est défini comme un objet avec une clé recordType définie sur "empty".

const emptyRecord = {
  recordType: "empty"
};

const ndef = new NDEFReader();
await ndef.write({ records: [emptyRecord] });

Prise en charge des navigateurs

Le NFC Web est disponible sur Android dans Chrome 89.

Conseils pour les développeurs

Voici une liste de choses que j'aurais aimé savoir quand j'ai commencé à utiliser la technologie Web NFC:

  • Android gère les tags NFC au niveau du système d'exploitation avant que la technologie Web NFC ne soit opérationnelle.
  • Vous trouverez une icône NFC sur material.io.
  • Utilisez l'enregistrement NDEF id pour identifier facilement un enregistrement en cas de besoin.
  • Un tag NFC non formaté compatible avec NDEF contient un seul enregistrement du type vide.
  • Il est facile d'écrire un enregistrement d'application Android, comme illustré ci-dessous.
const encoder = new TextEncoder();
const aarRecord = {
  recordType: "android.com:pkg",
  data: encoder.encode("com.example.myapp")
};

const ndef = new NDEFReader();
await ndef.write({ records: [aarRecord] });

Démonstrations

Essayez l'extrait officiel et consultez des démos intéressantes de la technologie Web NFC:

Démonstration des cartes Web NFC au Chrome Dev Summit 2019

Commentaires

Le groupe de la communauté Web NFC et l'équipe Chrome aimeraient connaître votre avis et vos expériences concernant la technologie Web NFC.

Décrivez-nous la conception de l'API.

Y a-t-il quelque chose dans l'API qui ne fonctionne pas comme prévu ? Ou y a-t-il des méthodes ou des propriétés manquantes dont vous avez besoin pour mettre en œuvre votre idée ?

Signalez un problème de spécification sur le dépôt GitHub Web NFC ou ajoutez vos commentaires à un problème existant.

Signaler un problème d'implémentation

Avez-vous détecté un bug dans l'implémentation de Chrome ? Ou l'implémentation est-elle différente des spécifications ?

Signalez un bug à l'adresse https://new.crbug.com. Veillez à inclure autant de détails que possible, à fournir des instructions simples pour reproduire le bug et à définir l'option Composants sur Blink>NFC. Glitch est idéal pour partager des reproductions rapides et faciles.

Afficher le soutien

Prévoyez-vous d'utiliser la technologie Web NFC ? Votre assistance publique aide l'équipe Chrome à prioriser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge.

Envoyez un tweet à @ChromiumDev avec le hashtag #WebNFC, et indiquez-nous où et comment vous l'utilisez.

Liens utiles

Remerciements

Un grand merci aux collaborateurs Intel pour avoir implémenté Web NFC. Google Chrome dépend d'une communauté de contributeurs qui travaillent ensemble pour faire avancer le projet Chromium. Tous les contributeurs Chromium ne sont pas des Googleurs, et ces contributeurs méritent une reconnaissance spéciale.