Communiceer met NFC-apparaten in Chrome voor Android

Lezen en schrijven naar NFC-tags is nu mogelijk.

François Beaufort
François Beaufort

Wat is Web-NFC?

NFC staat voor Near Field Communications, een draadloze technologie met een kort bereik die werkt op 13,56 MHz en die communicatie mogelijk maakt tussen apparaten op een afstand van minder dan 10 cm en een transmissiesnelheid tot 424 kbit/s.

Web NFC biedt sites de mogelijkheid om NFC-tags te lezen en ernaar te schrijven wanneer deze zich in de buurt van het apparaat van de gebruiker bevinden (meestal 5-10 cm, 2-4 inch). Het huidige bereik is beperkt tot NFC Data Exchange Format (NDEF), een lichtgewicht binair berichtformaat dat met verschillende tagformaten werkt.

Telefoon die een NFC-tag inschakelt om gegevens uit te wisselen
Diagram van een NFC-bewerking

Voorgestelde gebruiksscenario's

Web NFC is beperkt tot NDEF omdat de beveiligingseigenschappen van het lezen en schrijven van NDEF-gegevens gemakkelijker kwantificeerbaar zijn. Low-level I/O-bewerkingen (bijv. ISO-DEP, NFC-A/B, NFC-F), Peer-to-Peer-communicatiemodus en Host-based Card Emulation (HCE) worden niet ondersteund.

Voorbeelden van sites die Web NFC kunnen gebruiken zijn:

  • Musea en kunstgalerijen kunnen aanvullende informatie over een tentoonstelling weergeven wanneer de gebruiker met zijn apparaat een NFC-kaart in de buurt van de tentoonstelling aanraakt.
  • Voorraadbeheersites kunnen gegevens lezen of schrijven naar de NFC-tag op een container om informatie over de inhoud ervan bij te werken.
  • Conferentielocaties kunnen het gebruiken om NFC-badges tijdens het evenement te scannen en ervoor te zorgen dat ze worden vergrendeld om verdere wijzigingen in de informatie die erop staat te voorkomen.
  • Sites kunnen het gebruiken voor het delen van initiële geheimen die nodig zijn voor scenario's voor het inrichten van apparaten of services, en ook voor het implementeren van configuratiegegevens in de operationele modus.
Telefoon scant verschillende NFC-tags
NFC-inventarisbeheer geïllustreerd

Huidige status

Stap Toestand
1. Maak een uitleg Compleet
2. Maak een eerste ontwerp van specificatie Compleet
3. Verzamel feedback en herhaal het ontwerp Compleet
4. Oorsprongsproces Compleet
5. Lancering Compleet

Gebruik Web-NFC

Functiedetectie

Functiedetectie voor hardware is anders dan u waarschijnlijk gewend bent. De aanwezigheid van NDEFReader vertelt je dat de browser Web NFC ondersteunt, maar niet of de benodigde hardware aanwezig is. Met name als de hardware ontbreekt, zal de belofte die door bepaalde oproepen wordt geretourneerd, worden afgewezen. Ik zal details geven wanneer ik NDEFReader beschrijf.

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

Terminologie

Een NFC-tag is een passief NFC-apparaat, wat betekent dat het wordt aangedreven door magnetische inductie wanneer een actief NFC-apparaat (zoals een telefoon) in de buurt is. NFC-tags zijn er in vele vormen en modes, zoals stickers, creditcards, armpolsen en meer.

Foto van een transparante NFC-tag
Een transparante NFC-tag

Het NDEFReader object is het toegangspunt in Web NFC dat functionaliteit biedt voor het voorbereiden van lees- en/of schrijfacties die worden uitgevoerd wanneer een NDEF-tag in de buurt komt. De NDEF in NDEFReader staat voor NFC Data Exchange Format, een lichtgewicht binair berichtformaat gestandaardiseerd door het NFC Forum .

Het NDEFReader object dient om te reageren op inkomende NDEF-berichten van NFC-tags en om NDEF-berichten te schrijven naar NFC-tags binnen bereik.

Een NFC-tag die NDEF ondersteunt, is als een post-it-briefje. Iedereen kan het lezen, en tenzij het alleen-lezen is, kan iedereen ernaar schrijven. Het bevat een enkel NDEF-bericht dat een of meer NDEF-records omvat. Elke NDEF-record is een binaire structuur die een gegevenspayload en bijbehorende type-informatie bevat. Web NFC ondersteunt de volgende gestandaardiseerde recordtypen van NFC Forum: leeg, tekst, URL, slimme poster, MIME-type, absolute URL, extern type, onbekend en lokaal type.

Diagram van een NDEF-bericht
Diagram van een NDEF-bericht

NFC-tags scannen

Om NFC-tags te scannen, moet u eerst een nieuw NDEFReader object instantiëren. Het aanroepen van scan() retourneert een belofte. De gebruiker kan een melding krijgen als er niet eerder toegang is verleend. De belofte zal worden opgelost als aan alle volgende voorwaarden is voldaan:

  • Het werd alleen opgeroepen als reactie op een gebruikersgebaar, zoals een aanraakgebaar of een muisklik.
  • De gebruiker heeft toegestaan ​​dat de website communiceert met NFC-apparaten.
  • De telefoon van de gebruiker ondersteunt NFC.
  • De gebruiker heeft NFC op zijn telefoon ingeschakeld.

Zodra de belofte is opgelost, zijn inkomende NDEF-berichten beschikbaar door u te abonneren op reading via een gebeurtenislistener. U moet zich ook abonneren op readingerror gebeurtenissen om op de hoogte te worden gesteld wanneer incompatibele NFC-tags in de buurt zijn.

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}.`);
});

Wanneer een NFC-tag in de buurt is, wordt een NDEFReadingEvent gebeurtenis geactiveerd. Het bevat twee unieke eigenschappen:

  • serialNumber vertegenwoordigt het serienummer van het apparaat (bijvoorbeeld 00-11-22-33-44-55-66), of een lege string als er geen beschikbaar is.
  • message vertegenwoordigt het NDEF-bericht dat is opgeslagen in de NFC-tag.

Als u de inhoud van het NDEF-bericht wilt lezen, doorloopt u message.records en verwerkt u de data op de juiste manier op basis van hun recordType . Het data wordt weergegeven als een DataView , omdat het gevallen mogelijk maakt waarin gegevens zijn gecodeerd in 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.
    }
  }
};

Schrijf NFC-tags

Om NFC-tags te schrijven, moet u eerst een nieuw NDEFReader object instantiëren. Het aanroepen van write() retourneert een belofte. De gebruiker kan een melding krijgen als er niet eerder toegang is verleend. Op dit punt is een NDEF-bericht "voorbereid" en wordt de belofte opgelost als aan de volgende voorwaarden is voldaan:

  • Het werd alleen opgeroepen als reactie op een gebruikersgebaar, zoals een aanraakgebaar of een muisklik.
  • De gebruiker heeft toegestaan ​​dat de website communiceert met NFC-apparaten.
  • De telefoon van de gebruiker ondersteunt NFC.
  • De gebruiker heeft NFC op zijn telefoon ingeschakeld.
  • De gebruiker heeft op een NFC-tag getikt en er is een NDEF-bericht geschreven.

Om tekst naar een NFC-tag te schrijven, geeft u een tekenreeks door aan de methode write() .

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

Als u een URL-record naar een NFC-tag wilt schrijven, geeft u een woordenboek door dat een NDEF-bericht vertegenwoordigt aan write() . In het onderstaande voorbeeld is het NDEF-bericht een woordenboek met een records . De waarde ervan is een array van records - in dit geval een URL-record die is gedefinieerd als een object met een recordType sleutel ingesteld op "url" en een data ingesteld op de URL-tekenreeks.

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}.`);
});

Het is ook mogelijk om meerdere records naar een NFC-tag te schrijven.

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}.`);
});

Als de NFC-tag een NDEF-bericht bevat dat niet mag worden overschreven, stelt u de eigenschap overwrite in op false in de opties die worden doorgegeven aan de methode write() . In dat geval wordt de geretourneerde belofte afgewezen als er al een NDEF-bericht in de NFC-tag is opgeslagen.

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}.`);
});

Maak NFC-tags alleen-lezen

Om te voorkomen dat kwaadwillende gebruikers de inhoud van een NFC-tag overschrijven, is het mogelijk om NFC-tags permanent alleen-lezen te maken. Deze handeling is een eenrichtingsproces en kan niet ongedaan worden gemaakt. Zodra een NFC-tag alleen-lezen is gemaakt, kan er niet meer naar worden geschreven.

Om NFC-tags alleen-lezen te maken, moet u eerst een nieuw NDEFReader object instantiëren. Het aanroepen van makeReadOnly() retourneert een belofte. De gebruiker kan een melding krijgen als er niet eerder toegang is verleend. De belofte zal worden opgelost als aan alle volgende voorwaarden is voldaan:

  • Het werd alleen opgeroepen als reactie op een gebruikersgebaar, zoals een aanraakgebaar of een muisklik.
  • De gebruiker heeft toegestaan ​​dat de website communiceert met NFC-apparaten.
  • De telefoon van de gebruiker ondersteunt NFC.
  • De gebruiker heeft NFC op zijn telefoon ingeschakeld.
  • De gebruiker heeft op een NFC-tag getikt en de NFC-tag is met succes alleen-lezen gemaakt.
const ndef = new NDEFReader();
ndef.makeReadOnly()
.then(() => {
  console.log("NFC tag has been made permanently read-only.");
}).catch(error => {
  console.log(`Operation failed: ${error}`);
});

Hier ziet u hoe u een NFC-tag permanent alleen-lezen kunt maken nadat u ernaar hebt geschreven.

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}`);
}

Omdat makeReadOnly() beschikbaar is op Android in Chrome 100 of hoger, controleer of deze functie wordt ondersteund met het volgende:

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

Beveiliging en machtigingen

Het Chrome-team heeft Web NFC ontworpen en geïmplementeerd met behulp van de kernprincipes die zijn gedefinieerd in Toegangscontrole tot krachtige webplatformfuncties , waaronder gebruikerscontrole, transparantie en ergonomie.

Omdat NFC het domein van informatie uitbreidt die mogelijk beschikbaar is voor kwaadwillende websites, wordt de beschikbaarheid van NFC beperkt om het bewustzijn en de controle van gebruikers over NFC-gebruik te maximaliseren.

Schermafbeelding van een Web NFC-prompt op een website
Web NFC-gebruikersprompt

Web NFC is alleen beschikbaar voor frames op het hoogste niveau en beveiligde browsercontexten (alleen HTTPS). Origins moet eerst de toestemming "nfc" aanvragen tijdens het verwerken van een gebruikersgebaar (bijvoorbeeld een klik op een knop). De methoden NDEFReader scan() , write() en makeReadOnly() activeren een gebruikersprompt als er niet eerder toegang is verleend.

  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.
    };
  };

De combinatie van een door de gebruiker geïnitieerde toestemmingsprompt en fysieke beweging in de echte wereld waarbij het apparaat over een doel-NFC-tag wordt gebracht, weerspiegelt het kiespatroon dat wordt aangetroffen in de andere API's voor bestands- en apparaattoegang.

Om te kunnen scannen of schrijven, moet de webpagina zichtbaar zijn wanneer de gebruiker een NFC-tag aanraakt met zijn apparaat. De browser gebruikt haptische feedback om een ​​tik aan te geven. De toegang tot de NFC-radio wordt geblokkeerd als het display is uitgeschakeld of het apparaat is vergrendeld. Voor niet-zichtbare webpagina's wordt het ontvangen en pushen van NFC-inhoud opgeschort en hervat zodra een webpagina weer zichtbaar wordt.

Dankzij de Page Visibility API is het mogelijk om bij te houden wanneer de zichtbaarheid van documenten verandert.

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

Kookboek

Hier volgen enkele codevoorbeelden om u op weg te helpen.

Controleer of er toestemming is

Met de Permissions API kunt u controleren of de machtiging "nfc" is verleend. Dit voorbeeld laat zien hoe u NFC-tags kunt scannen zonder gebruikersinteractie als er eerder toegang is verleend, of hoe u op een andere manier een knop kunt weergeven. Merk op dat hetzelfde mechanisme werkt voor het schrijven van NFC-tags, omdat het dezelfde toestemming onder de motorkap gebruikt.

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();
  };
}

NFC-bewerkingen afbreken

Het gebruik van de Primitive AbortController maakt het eenvoudig om NFC-bewerkingen af ​​te breken. In het onderstaande voorbeeld ziet u hoe u het signal van een AbortController via de opties van NDEFReader scan() , makeReadOnly() , write() kunt doorgeven en beide NFC-bewerkingen tegelijkertijd kunt afbreken.

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();
};

Lees na schrijf

Door write() en vervolgens scan() te gebruiken met de primitief AbortController , wordt het mogelijk een NFC-tag te lezen nadat er een bericht naartoe is geschreven. In het onderstaande voorbeeld ziet u hoe u een sms-bericht naar een NFC-tag schrijft en het nieuwe bericht in de NFC-tag leest. Het stopt met scannen na drie seconden.

// 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.

Een tekstrecord lezen en schrijven

De data kunnen worden gedecodeerd met een TextDecoder die is geïnstantieerd met de encoding . Houd er rekening mee dat de taal van het tekstrecord beschikbaar is via de lang eigenschap.

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

Om een ​​eenvoudig tekstrecord te schrijven, geeft u een tekenreeks door aan de NDEFReader write() -methode.

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

Tekstrecords zijn standaard UTF-8 en gaan uit van de taal van het huidige document, maar beide eigenschappen ( encoding en lang ) kunnen worden opgegeven met behulp van de volledige syntaxis voor het maken van een aangepast NDEF-record.

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] });

Lees en schrijf een URL-record

Gebruik TextDecoder om de data te decoderen.

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

Om een ​​URL-record te schrijven, geeft u een NDEF-berichtenwoordenboek door aan de NDEFReader write() -methode. Het URL-record in het NDEF-bericht wordt gedefinieerd als een object met een recordType sleutel ingesteld op "url" en een data ingesteld op de URL-tekenreeks.

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

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

Lees en schrijf een MIME-type record

De eigenschap mediaType van een record van het MIME-type vertegenwoordigt het MIME-type van de payload van de NDEF-record, zodat data correct kunnen worden gedecodeerd. Gebruik bijvoorbeeld JSON.parse om JSON-tekst te decoderen en een Image-element om afbeeldingsgegevens te decoderen.

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.
  }
}

Om een ​​MIME-type record te schrijven, geeft u een NDEF-berichtenwoordenboek door aan de NDEFReader write() -methode. Het MIME-type record in het NDEF-bericht wordt gedefinieerd als een object met een recordType sleutel ingesteld op "mime" , een mediaType -sleutel ingesteld op het daadwerkelijke MIME-type van de inhoud en een data ingesteld op een object dat een ArrayBuffer of biedt een weergave van een ArrayBuffer (bijv. 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] });

Lees en schrijf een absolute URL-record

De absolute URL- data kunnen worden gedecodeerd met een eenvoudige TextDecoder .

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

Om een ​​absolute URL-record te schrijven, geeft u een NDEF-berichtenwoordenboek door aan de NDEFReader write() -methode. Het absolute URL-record in het NDEF-bericht wordt gedefinieerd als een object met een recordType sleutel ingesteld op "absolute-url" en een data ingesteld op de URL-tekenreeks.

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

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

Lees en schrijf een slim posterrecord

Een slim posterrecord (gebruikt in tijdschriftadvertenties, flyers, billboards, enz.) beschrijft bepaalde webinhoud als een NDEF-record dat een NDEF-bericht als payload bevat. Roep record.toRecords() aan om data te transformeren naar een lijst met records in het slimme posterrecord. Het moet een URL-record hebben, een tekstrecord voor de titel, een MIME-typerecord voor de afbeelding en enkele aangepaste lokale typerecords zoals respectievelijk ":t" , ":act" en ":s" voor het type, actie en de grootte van het slimme posterrecord.

Records van het lokale type zijn alleen uniek binnen de lokale context van het bevattende NDEF-record. Gebruik ze wanneer de betekenis van de typen er niet toe doet buiten de lokale context van het bevattende record en wanneer opslaggebruik een harde beperking is. Recordnamen van lokale typen beginnen altijd met : in Web NFC (bijv. ":t" , ":s" , ":act" ). Dit is bijvoorbeeld bedoeld om een ​​tekstrecord te onderscheiden van een tekstrecord van het lokale type.

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;
  }
}

Om een ​​smart poster-record te schrijven, geeft u een NDEF-bericht door aan de NDEFReader write() -methode. Het slimme posterrecord in het NDEF-bericht wordt gedefinieerd als een object met een recordType sleutel ingesteld op "smart-poster" en een data ingesteld op een object dat (opnieuw) een NDEF-bericht vertegenwoordigt dat is opgenomen in het slimme posterrecord.

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] });

Een extern typerecord lezen en schrijven

Gebruik externe typerecords om door de toepassing gedefinieerde records te maken. Deze kunnen een NDEF-bericht als payload bevatten dat toegankelijk is met toRecords() . Hun naam bevat de domeinnaam van de uitgevende organisatie, een dubbele punt en een typenaam die minimaal één teken lang is, bijvoorbeeld "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.
    }
  }
}

Als u een record van een extern type wilt schrijven, geeft u een NDEF-berichtenwoordenboek door aan de methode NDEFReader write() . Het externe typerecord in het NDEF-bericht wordt gedefinieerd als een object met een recordType sleutel ingesteld op de naam van het externe type en een data ingesteld op een object dat een NDEF-bericht vertegenwoordigt dat is opgenomen in het externe typerecord. Merk op dat de data ook een ArrayBuffer kan zijn of een weergave van een ArrayBuffer kan bieden (bijvoorbeeld 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] });

Lees en schrijf een leeg record

Een leeg record heeft geen payload.

Om een ​​leeg record te schrijven, geeft u een NDEF-berichtenwoordenboek door aan de NDEFReader write() -methode. De lege record in het NDEF-bericht wordt gedefinieerd als een object met een recordType sleutel ingesteld op "empty" .

const emptyRecord = {
  recordType: "empty"
};

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

Browser-ondersteuning

Web NFC is beschikbaar op Android in Chrome 89.

Ontwikkelaarstips

Hier is een lijst met dingen die ik graag had geweten toen ik begon te spelen met Web NFC:

  • Android verwerkt NFC-tags op besturingssysteemniveau voordat Web NFC operationeel is.
  • Je vindt een NFC-pictogram op material.io .
  • Gebruik de NDEF-record- id om eenvoudig een record te identificeren wanneer dat nodig is.
  • Een ongeformatteerde NFC-tag die NDEF ondersteunt, bevat één record van het lege type.
  • Het schrijven van een Android-applicatierecord is eenvoudig, zoals hieronder weergegeven.
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] });

Demo's

Probeer het officiële voorbeeld en bekijk enkele coole Web NFC-demo's:

Demo voor Web NFC-kaarten op Chrome Dev Summit 2019

Feedback

De Web NFC Community Group en het Chrome-team horen graag uw mening en ervaringen met Web NFC.

Vertel ons over het API-ontwerp

Is er iets aan de API dat niet werkt zoals verwacht? Of ontbreken er methoden of eigenschappen die je nodig hebt om je idee te implementeren?

Dien een spec-probleem in op de Web NFC GitHub-opslagplaats of voeg uw mening toe aan een bestaand probleem.

Meld een probleem met de implementatie

Heeft u een bug gevonden in de implementatie van Chrome? Of wijkt de uitvoering af van de specificaties?

Dien een bug in op https://new.crbug.com . Zorg ervoor dat u zoveel mogelijk details vermeldt, geef eenvoudige instructies voor het reproduceren van de bug en zorg ervoor dat Componenten zijn ingesteld op Blink>NFC . Glitch werkt uitstekend voor het delen van snelle en gemakkelijke reproducties.

Toon steun

Bent u van plan Web NFC te gebruiken? Uw publieke steun helpt het Chrome-team prioriteiten te stellen voor functies en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen.

Stuur een tweet naar @ChromiumDev met de hashtag #WebNFC en laat ons weten waar en hoe u deze gebruikt.

Handige Links

Dankbetuigingen

Hartelijk dank aan de mensen bij Intel voor de implementatie van Web NFC. Google Chrome is afhankelijk van een gemeenschap van committers die samenwerken om het Chromium-project vooruit te helpen. Niet elke Chromium-committer is een Googler, en deze bijdragers verdienen speciale erkenning!