Interagir avec des appareils NFC sur Chrome pour Android

Il est désormais possible de lire et d'écrire sur les tags NFC.

François Beaufort
François Beaufort

Qu'est-ce que Web NFC ?

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

Web NFC permet aux sites de lire et d'écrire des tags NFC lorsqu'ils se trouvent à proximité de l'appareil de l'utilisateur (généralement entre 5 et 10 cm). La portée actuelle est limitée au format d'échange de données NFC (NDEF), un format de message binaire léger qui fonctionne avec différents formats de tags.

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

Cas d'utilisation suggérés

Web NFC est limité à 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 compatibles.

Voici quelques exemples de sites pouvant utiliser Web NFC :

  • Les musées et les galeries d'art peuvent afficher des informations supplémentaires sur une exposition lorsque l'utilisateur approche son appareil d'une carte NFC près de l'exposition.
  • Les sites de gestion des stocks peuvent lire ou écrire des données sur la balise NFC d'un conteneur pour mettre à jour les informations sur son contenu.
  • Les organisateurs de conférences peuvent l'utiliser pour scanner les badges NFC pendant l'événement et s'assurer qu'ils sont verrouillés pour empêcher toute modification ultérieure des informations qui y sont inscrites.
  • Les sites peuvent l'utiliser pour partager les secrets initiaux nécessaires aux scénarios de provisionnement d'appareils ou de services, mais aussi pour déployer des données de configuration en mode opérationnel.
Téléphone scannant plusieurs tags NFC
Gestion des stocks NFC illustrée

État actuel

Étape État
1. Créer une explication Fin
2. Créer une première ébauche de spécification Fin
3. Recueillir des commentaires et améliorer la conception Fin
4. Essai Origin Trial Fin
5. Lancer Fin

Utiliser Web NFC

Détection de caractéristiques

La détection des fonctionnalités matérielles est différente de celle à laquelle vous êtes probablement habitué. La présence de NDEFReader indique que le navigateur est compatible avec Web NFC, 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 refusée. Je vous donnerai plus de 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, ce qui signifie qu'il est alimenté par induction magnétique lorsqu'un appareil NFC actif (tel qu'un téléphone) se trouve à proximité. Les balises NFC se présentent sous de nombreuses formes, comme des autocollants, des cartes de crédit, des bracelets, etc.

Photo d'un tag NFC transparent
Tag NFC transparent

L'objet NDEFReader est le point d'entrée dans Web NFC qui expose des fonctionnalités permettant de préparer des actions de lecture et/ou d'écriture qui sont exécutées lorsqu'une balise NDEF se trouve à proximité. Le NDEF dans NDEFReader signifie "NFC Data Exchange Format", un format de message binaire léger standardisé par le NFC Forum.

L'objet NDEFReader permet d'agir sur les messages NDEF entrants provenant de tags NFC et d'écrire des messages NDEF sur des tags NFC à portée.

Un tag NFC compatible avec NDEF est comme 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 qui contient une charge utile de données et des informations de type associées. Web NFC est compatible avec les types d'enregistrements standardisés du NFC Forum suivants : vide, texte, URL, smart poster, type MIME, URL absolue, type externe, type inconnu et type local.

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

Scanner des tags NFC

Pour scanner des tags NFC, commencez par instancier un nouvel objet NDEFReader. L'appel scan() renvoie une promesse. L'utilisateur peut être invité à accorder l'accès s'il ne l'a pas fait auparavant. La promesse sera résolue si toutes les conditions suivantes sont remplies :

  • Elle n'a été appelée 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 les appareils NFC.
  • Le téléphone de l'utilisateur est compatible avec la technologie NFC.
  • L'utilisateur a activé le NFC sur son téléphone.

Une fois la promesse résolue, les messages NDEF entrants sont disponibles en s'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 est à 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 numéro n'est disponible.
  • message représente le message NDEF stocké dans la balise NFC.

Pour lire le contenu du message NDEF, parcourez message.records et traitez ses 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 en 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, commencez par instancier un nouvel objet NDEFReader. L'appel write() renvoie une promesse. L'utilisateur peut être invité à accorder l'accès s'il ne l'a pas fait auparavant. À ce stade, un message NDEF est "préparé" et la promesse sera résolue si toutes les conditions suivantes sont remplies :

  • Elle n'a été appelée 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 les appareils NFC.
  • Le téléphone de l'utilisateur est compatible avec la technologie NFC.
  • L'utilisateur a activé le NFC sur son téléphone.
  • L'utilisateur a appuyé sur une balise NFC et un message NDEF a été écrit.

Pour écrire du texte sur 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 sur un tag NFC, transmettez un dictionnaire représentant un message NDEF à write(). Dans l'exemple ci-dessous, le message NDEF est un dictionnaire avec une clé records. Sa valeur est un tableau d'enregistrements. Dans ce cas, il s'agit d'un enregistrement d'URL 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 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 un tag 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 ne doit pas ê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 refusée si un message NDEF est déjà stocké dans la balise 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}.`);
});

Rendre les tags NFC en lecture seule

Pour empêcher les utilisateurs malveillants d'écraser 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 irréversible. Une fois qu'un tag NFC a été défini en lecture seule, il ne peut plus être écrit.

Pour rendre les tags NFC en lecture seule, commencez par instancier un nouvel objet NDEFReader. L'appel makeReadOnly() renvoie une promesse. L'utilisateur peut être invité à accorder l'accès s'il ne l'a pas fait auparavant. La promesse sera résolue si toutes les conditions suivantes sont remplies :

  • Elle n'a été appelée 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 les appareils NFC.
  • Le téléphone de l'utilisateur est compatible avec la technologie NFC.
  • L'utilisateur a activé le NFC sur son téléphone.
  • L'utilisateur a appuyé sur un tag NFC, qui a bien été défini 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 rendre une balise NFC en lecture seule de manière permanente après y avoir écrit des données.

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 prise en charge 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 implémenté Web NFC en utilisant les principes fondamentaux définis dans Controlling Access to Powerful Web Platform Features, y compris le contrôle utilisateur, la transparence et l'ergonomie.

Étant donné que la technologie NFC élargit le domaine des informations potentiellement disponibles pour les sites Web malveillants, sa disponibilité est limitée afin de maximiser la sensibilisation et le contrôle des utilisateurs sur son utilisation.

Capture d'écran d'une invite Web NFC sur un site Web
Invite utilisateur Web NFC

Web NFC n'est disponible que pour les cadres de premier niveau 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é accordé précédemment.

  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 initiée par l'utilisateur et d'un mouvement physique réel consistant à placer l'appareil au-dessus d'une balise NFC cible reflète le modèle de sélecteur trouvé dans les autres API d'accès aux fichiers et aux appareils.

Pour effectuer une lecture 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 un appui. L'accès à la 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 l'envoi de contenu NFC sont suspendus et reprennent lorsqu'une page Web redevient visible.

Grâce à l'API Page Visibility, il est possible de suivre les changements 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 à vous lancer.

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 afficher un bouton dans le cas contraire. Notez que le même mécanisme fonctionne pour l'écriture des 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 facilite l'abandon des opérations NFC. L'exemple ci-dessous 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 montre comment écrire un message texte sur une balise NFC et lire le nouveau message dans la balise NFC. L'analyse 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 de texte

L'enregistrement de 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 au format 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() de 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 afin que data puisse être décodé correctement. Par exemple, utilisez JSON.parse pour décoder le 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 NDEFReader write(). 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 un ArrayBuffer ou fournir une vue sur un ArrayBuffer (par exemple, Uint8Array, 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 absolue, 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 écrire un enregistrement de smart poster

Un enregistrement de smart poster (utilisé dans les publicités de magazines, les prospectus, les panneaux d'affichage, etc.) décrit un contenu Web en tant qu'enregistrement NDEF contenant un message NDEF comme charge utile. Appelez record.toRecords() pour transformer data en liste d'enregistrements contenus dans l'enregistrement de l'affiche intelligente. Il doit comporter un enregistrement d'URL, un enregistrement de texte pour le titre, un enregistrement de type MIME pour l'image et des enregistrements de type local personnalisé tels que ":t", ":act" et ":s" respectivement pour le type, l'action et la taille de l'enregistrement de l'affiche intelligente.

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 des enregistrements de type local commencent toujours par : dans Web NFC (par exemple, ":t", ":s", ":act"). Cela permet de différencier un enregistrement de texte d'un enregistrement de 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 de smart poster, transmettez un message NDEF à la méthode write() de NDEFReader. L'enregistrement de smart poster contenu dans le message NDEF est défini comme un objet dont la clé recordType est définie sur "smart-poster" et la clé data est définie sur un objet qui représente (une fois de plus) un message NDEF contenu dans l'enregistrement de smart poster.

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. Ils peuvent contenir un message NDEF comme charge utile, accessible avec toRecords(). Leur nom contient le nom de domaine de l'organisation émettrice, un 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() de 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 qui représente un message NDEF contenu dans l'enregistrement de type externe. Notez que la clé data peut également être un ArrayBuffer ou fournir une vue sur un ArrayBuffer (par exemple, Uint8Array, 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 ne comporte aucune charge utile.

Pour écrire un enregistrement vide, transmettez un dictionnaire de messages NDEF à la méthode write() de 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

Web NFC est disponible sur Android dans Chrome 89.

Conseils pour les développeurs

Voici une liste de choses que j'aurais aimé savoir lorsque j'ai commencé à jouer avec Web NFC :

  • Android gère les tags NFC au niveau de l'OS avant que Web NFC ne soit opérationnel.
  • Vous trouverez une icône NFC sur material.io.
  • Utilisez l'enregistrement NDEF id pour identifier facilement un enregistrement si nécessaire.
  • Une balise NFC non formatée compatible avec NDEF contient un seul enregistrement de type vide.
  • Il est facile d'écrire un enregistrement d'application Android, comme indiqué 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'exemple officiel et découvrez quelques démos Web NFC intéressantes :

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

Commentaires

Le Web NFC Community Group et l'équipe Chrome aimeraient connaître votre avis et votre expérience avec Web NFC.

Parlez-nous de la conception de l'API

Y a-t-il un élément de l'API qui ne fonctionne pas comme prévu ? Ou bien manquent-ils des méthodes ou des propriétés dont vous avez besoin pour mettre en œuvre votre idée ?

Signalez un problème lié aux spécifications dans le dépôt GitHub Web NFC ou ajoutez vos commentaires à un problème existant.

Signaler un problème d'implémentation

Avez-vous trouvé un bug dans l'implémentation de Chrome ? Ou l'implémentation est-elle différente de la spécification ?

Signalez un bug sur https://new.crbug.com. Veillez à inclure autant de détails que possible, à fournir des instructions simples pour reproduire le bug et à définir Composants sur Blink>NFC.

Montrer votre soutien

Prévoyez-vous d'utiliser Web NFC ? Votre soutien public aide l'équipe Chrome à hiérarchiser 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 pour nous indiquer où et comment vous l'utilisez.

Liens utiles

Remerciements

Un grand merci à l'équipe d'Intel pour l'implémentation de Web NFC. Google Chrome dépend d'une communauté de contributeurs qui travaillent ensemble pour faire avancer le projet Chromium. Tous les committers Chromium ne sont pas des employés Google. Ces contributeurs méritent une reconnaissance particulière.