在 Android 版 Google Chrome 與 NFC 裝置互動

現可讀取及寫入 NFC 標記。

François Beaufort
François Beaufort

什麼是 Web NFC?

NFC 代表近距離無線通訊,這是一種短距離無線技術,頻率為 13.56 MHz,可讓裝置在距離不到 10 公分時進行通訊,傳輸速率最高可達 424 kbit/s。

Web NFC 可讓網站在 NFC 感應標籤靠近使用者裝置 (通常為 5 到 10 公分,即 2 到 4 英寸) 時,讀取及寫入 NFC 感應標籤。目前的範圍僅限於 NFC 資料交換格式 (NDEF),這是一種輕量二進位訊息格式,可跨不同標記格式運作。

手機啟動 NFC 標記以交換資料
NFC 作業流程圖

建議用途

Web NFC 僅限於 NDEF,因為讀取和寫入 NDEF 資料的安全性屬性較容易量化。不支援低階 I/O 作業 (例如 ISO-DEP、NFC-A/B、NFC-F)、對等端通訊模式和主機式卡片模擬 (HCE)。

以下列舉一些可能會使用 Web NFC 的網站:

  • 當使用者將裝置輕觸展覽品附近的 NFC 卡時,博物館和藝廊就能顯示相關資訊。
  • 商品目錄管理網站可以讀取或寫入容器上的 NFC 標籤資料,以更新內容資訊。
  • 會議網站可在活動期間使用這項功能掃描 NFC 徽章,並確保徽章已上鎖,以免日後變更其上寫的資訊。
  • 網站可以使用這項功能,分享裝置或服務佈建情境所需的初始密鑰,並在運作模式中部署設定資料。
手機掃描多個 NFC 標記
NFC 庫存管理示意圖

目前狀態

步驟 狀態
1. 建立說明 完成
2. 建立規格初稿 完成
3. 收集意見回饋並重複設計 完成
4. 來源試用 完成
5. 啟動 完成

使用 Web NFC

特徵偵測

硬體功能偵測與您可能習慣的方式不同。NDEFReader 的存在表示瀏覽器支援 Web NFC,但不表示裝置有必要的硬體。特別是,如果缺少硬體,則某些呼叫傳回的承諾會遭到拒絕。我會在說明 NDEFReader 時提供詳細資訊。

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

術語

NFC 標記是被動式 NFC 裝置,也就是說,當主動式 NFC 裝置 (例如手機) 靠近時,會透過磁力感應供電。NFC 標籤有多種形式和款式,例如貼紙、信用卡、手腕等。

透明 NFC 標記相片
透明 NFC 標記

NDEFReader 物件是 Web NFC 中的進入點,可提供功能,以便在 NDEF 標記靠近時,準備讀取和/或寫入動作。NDEFReader 中的 NDEF 代表 NFC 資料交換格式,這是由 NFC 論壇標準化的輕量二進位訊息格式。

NDEFReader 物件可用於處理來自 NFC 標記的傳入 NDEF 訊息,以及將 NDEF 訊息寫入範圍內的 NFC 標記。

支援 NDEF 的 NFC 標籤就像便利貼,任何人都可以讀取,而且除非是唯讀,否則任何人都能寫入。其中包含單一 NDEF 訊息,封裝一或多個 NDEF 記錄。每個 NDEF 記錄都是二進位結構,其中包含資料酬載和相關類型資訊。Web NFC 支援下列 NFC Forum 標準化記錄類型:空白、文字、網址、智慧海報、MIME 類型、絕對網址、外部類型、不明和本機類型。

NDEF 訊息圖表
NDEF 訊息圖表

掃描 NFC 標記

如要掃描 NFC 標籤,請先將新的 NDEFReader 物件例項化。呼叫 scan() 會傳回承諾。如果先前未授予存取權,系統可能會提示使用者。如果符合下列所有條件,承諾就會解析:

  • 只有在回應使用者手勢 (例如觸控手勢或滑鼠點擊) 時才會呼叫。
  • 使用者已允許網站與 NFC 裝置互動。
  • 使用者的手機支援 NFC。
  • 使用者已在手機上啟用 NFC。

承諾解決後,您可以透過事件監聽器訂閱 reading 事件,接收傳入的 NDEF 訊息。您也應訂閱 readingerror 事件,以便在相容的 NFC 標記在附近時收到通知。

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

當 NFC 標籤在附近時,系統會觸發 NDEFReadingEvent 事件。其中包含兩個專屬屬性:

  • serialNumber 代表裝置的序號 (例如 00-11-22-33-44-55-66),如果沒有序號,則為空字串。
  • message 代表儲存在 NFC 標記中的 NDEF 訊息。

如要讀取 NDEF 訊息的內容,請循環 message.records,並根據 recordType 處理其 data 成員data 成員會以 DataView 的形式公開,因為它可處理資料以 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.
    }
  }
};

寫入 NFC 標記

如要寫入 NFC 標記,請先將新的 NDEFReader 物件例項化。呼叫 write() 會傳回承諾。如果使用者先前未授予存取權,系統可能會提示使用者。此時,NDEF 訊息會處於「準備」狀態,且在滿足下列所有條件時,承諾會解析:

  • 只有在回應使用者手勢 (例如觸控手勢或滑鼠點擊) 時才會呼叫。
  • 使用者已允許網站與 NFC 裝置互動。
  • 使用者的手機支援 NFC。
  • 使用者已在手機上啟用 NFC。
  • 使用者已輕觸 NFC 標籤,且已成功寫入 NDEF 訊息。

如要將文字寫入 NFC 標記,請將字串傳遞至 write() 方法。

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

如要將網址記錄寫入 NFC 標記,請將代表 NDEF 訊息的字典傳遞至 write()。在下列範例中,NDEF 訊息是包含 records 鍵的字典。其值為記錄陣列,在本例中,網址記錄定義為物件,其中 recordType 鍵設為 "url",而 data 鍵設為網址字串。

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

您也可以將多個記錄寫入 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}.`);
});

如果 NFC 標記包含不應覆寫的 NDEF 訊息,請在傳遞至 write() 方法的選項中,將 overwrite 屬性設為 false。在這種情況下,如果 NFC 標籤中已儲存 NDEF 訊息,系統會傳回拒絕的承諾。

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

將 NFC 標記設為唯讀

為避免惡意使用者覆寫 NFC 標記的內容,您可以將 NFC 標記設為永久唯讀。這項操作是單向程序,無法復原。NFC 標籤一旦設為唯讀,就無法再寫入。

如要將 NFC 標籤設為唯讀,請先將新的 NDEFReader 物件例項化。呼叫 makeReadOnly() 會傳回承諾。如果使用者先前未授予存取權,系統可能會提示使用者。如果滿足下列所有條件,承諾就會解析:

  • 只有在回應使用者手勢 (例如觸控手勢或滑鼠點擊) 時才會呼叫。
  • 使用者已允許網站與 NFC 裝置互動。
  • 使用者的手機支援 NFC。
  • 使用者已在手機上啟用 NFC。
  • 使用者已輕觸 NFC 標記,且 NFC 標記已成功設為唯讀。
const ndef = new NDEFReader();
ndef.makeReadOnly()
.then(() => {
  console.log("NFC tag has been made permanently read-only.");
}).catch(error => {
  console.log(`Operation failed: ${error}`);
});

以下說明如何在寫入 NFC 標記後,將其設為永久唯讀。

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

makeReadOnly() 可在 Android 版 Chrome 100 以上版本中使用,請確認是否支援以下功能:

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

安全性和權限

Chrome 團隊根據「控管強大網頁平台功能的存取權」一文中定義的核心原則,設計並實作 Web NFC,包括使用者控管、資訊公開和人體工學。

由於 NFC 會擴大惡意網站可存取的資訊範圍,因此我們限制 NFC 的使用情形,以便使用者充分瞭解並控管 NFC 的使用情形。

網站上的 Web NFC 提示螢幕截圖
Web NFC 使用者提示

Web NFC 僅適用於頂層框架和安全的瀏覽內容 (僅限 HTTPS)。處理使用者手勢 (例如按下按鈕) 時,來源必須先要求 "nfc" 權限。如果先前未授予存取權,NDEFReader scan()write()makeReadOnly() 方法會觸發使用者提示。

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

使用者啟動的權限提示,以及將裝置移到目標 NFC 標記的實際物理動作,這兩者結合起來的選擇器模式與其他檔案和裝置存取 API 中的模式相同。

如要執行掃描或寫入作業,使用者必須用裝置觸碰 NFC 標籤,網頁才會顯示。瀏覽器會使用觸覺回饋來表示輕觸動作。如果螢幕關閉或裝置處於鎖定狀態,NFC 無線電將無法存取。對於非顯示的網頁,接收和推送 NFC 內容會暫停,並在網頁再次顯示時恢復。

有了 Page Visibility API,您就能追蹤文件瀏覽權限的變更時間。

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

食譜集

以下提供一些程式碼範例,協助您快速上手。

檢查權限

Permissions API 可讓您檢查是否已授予 "nfc" 權限。此範例說明如何在使用者先前授予存取權的情況下,不經使用者互動即可掃描 NFC 標籤,或在其他情況下顯示按鈕。請注意,寫入 NFC 標記時會使用相同的機制,因為它在幕後使用相同的權限。

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 作業

使用 AbortController 原始類別可輕鬆終止 NFC 作業。以下範例說明如何透過 NDEFReader scan()makeReadOnly()write() 方法的選項,傳遞 AbortControllersignal,並同時中止兩個 NFC 作業。

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

寫入後讀取

使用 write()scan()AbortController 原始碼,即可在寫入訊息後讀取 NFC 標記。以下範例說明如何將文字訊息寫入 NFC 標記,並讀取 NFC 標記中的新訊息。並在三秒後停止掃描。

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

讀取及寫入文字記錄

文字記錄 data 可透過使用記錄 encoding 屬性實例化的 TextDecoder 解碼。請注意,文字記錄的語言可透過其 lang 屬性取得。

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

如要寫入簡單的文字記錄,請將字串傳遞至 NDEFReader write() 方法。

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

文字記錄預設為 UTF-8,並假設目前文件的語言,但兩個屬性 (encodinglang) 皆可使用完整語法指定,以便建立自訂 NDEF 記錄。

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

讀取及寫入網址記錄

使用 TextDecoder 解碼記錄的 data

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

如要寫入網址記錄,請將 NDEF 訊息字典傳遞至 NDEFReader write() 方法。NDEF 訊息中包含的網址記錄定義為物件,其中 recordType 鍵設為 "url",而 data 鍵設為網址字串。

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

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

讀取及寫入 MIME 類型記錄

MIME 類型記錄的 mediaType 屬性代表 NDEF 記錄酬載的 MIME 類型,以便正確解碼 data。舉例來說,您可以使用 JSON.parse 解碼 JSON 文字,並使用 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.
  }
}

如要寫入 MIME 類型記錄,請將 NDEF 訊息字典傳遞至 NDEFReader write() 方法。NDEF 訊息中包含的 MIME 類型記錄會定義為物件,其中 recordType 鍵設為 "mime"mediaType 鍵設為內容的實際 MIME 類型,而 data 鍵設為物件,該物件可以是 ArrayBuffer 或提供 ArrayBuffer 的檢視畫面 (例如 Uint8ArrayDataView)。

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

讀取及寫入絕對網址記錄

絕對網址記錄 data 可透過簡單的 TextDecoder 解碼。

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

如要寫入絕對網址記錄,請將 NDEF 訊息字典傳遞至 NDEFReader write() 方法。NDEF 訊息中包含的絕對網址記錄會定義為物件,其中 recordType 鍵設為 "absolute-url",而 data 鍵則設為網址字串。

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

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

讀取及寫入智慧海報記錄

智慧海報記錄 (用於雜誌廣告、傳單、廣告牌等) 會將部分網站內容描述為 NDEF 記錄,其中包含 NDEF 訊息做為酬載。呼叫 record.toRecords() 即可將 data 轉換為智慧型海報記錄中包含的記錄清單。應包含網址記錄、標題的文字記錄、圖片的 MIME 類型記錄,以及一些自訂的本地類型記錄,例如 ":t"":act"":s",分別用於智慧型海報記錄的類型、動作和大小。

本地類型記錄僅在包含 NDEF 記錄的本地內容中才會是唯一的。當類型的含義在包含記錄的本機情境之外不重要,且儲存空間用量為硬性限制時,請使用這些類型。在 Web NFC 中,本機類型記錄名稱一律以 : 開頭 (例如 ":t"":s"":act")。這可區分文字記錄和本機類型文字記錄。

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

如要寫入智慧海報記錄,請將 NDEF 訊息傳遞至 NDEFReader write() 方法。NDEF 訊息中所含的智慧海報記錄定義為物件,其中 recordType 鍵設為 "smart-poster",而 data 鍵則設為代表智慧海報記錄中所含 NDEF 訊息的物件。

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

讀取及寫入外部類型記錄

如要建立應用程式定義的記錄,請使用外部類型記錄。這些檔案可能會包含 NDEF 訊息,做為可透過 toRecords() 存取的酬載。其名稱包含發布機構的網域名稱、冒號和至少一個字元的型別名稱,例如 "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.
    }
  }
}

如要寫入外部類型記錄,請將 NDEF 訊息字典傳遞至 NDEFReader write() 方法。NDEF 訊息中所含的外部類型記錄,定義為 recordType 鍵設為外部類型名稱,而 data 鍵設為代表外部類型記錄中所含 NDEF 訊息的物件。請注意,data 鍵也可以是 ArrayBuffer,或提供 ArrayBuffer 的檢視畫面 (例如 Uint8ArrayDataView)。

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

讀取及寫入空白記錄

空白記錄沒有酬載。

如要寫入空白記錄,請將 NDEF 訊息字典傳遞至 NDEFReader write() 方法。NDEF 訊息中包含的空白記錄定義為 recordType 鍵設為 "empty" 的物件。

const emptyRecord = {
  recordType: "empty"
};

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

瀏覽器支援

在 Android 上,Chrome 89 支援 Web NFC。

開發人員提示

以下是開始使用 Web NFC 時,我希望自己知道的事項:

  • Android 會在 Web NFC 運作前,在作業系統層級處理 NFC 標記。
  • 您可以在 material.io 上找到 NFC 圖示。
  • 使用 NDEF 記錄 id,在需要時輕鬆識別記錄。
  • 支援 NDEF 的未格式化 NFC 標記包含空值類型的單一記錄。
  • 編寫 Android 應用程式記錄很簡單,如下所示。
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] });

示範

請試用官方範例,並查看一些精彩的 Web NFC 示範:

2019 年 Chrome 開發人員大會的 Web NFC 卡示範

意見回饋

Web NFC 社群群組和 Chrome 團隊很樂意聽取你對 Web NFC 的想法和體驗。

請告訴我們 API 設計

API 是否有任何功能無法正常運作?或者,您是否缺少實作想法所需的方法或屬性?

請在 Web NFC GitHub 存放區中提出規格問題,或在現有問題中加入您的想法。

回報實作問題

你是否發現 Chrome 實作項目有錯誤?還是實作方式與規格不同?

請前往 https://new.crbug.com 提交錯誤。請務必盡可能提供詳細資訊,提供重現錯誤的簡單操作說明,並將「元件」設為 Blink>NFCGlitch 非常適合用來快速分享重現問題的做法。

顯示支援

您是否打算使用 Web NFC?你的公開支援內容有助於 Chrome 團隊決定功能優先順序,並向其他瀏覽器供應商顯示支援這些功能的重要性。

使用主題標記 #WebNFC 發送推文給 @ChromiumDev,告訴我們你在何處使用這項功能,以及使用方式。

實用連結

特別銘謝

在此要向Intel 團隊致上萬分謝,感謝他們實作了 Web NFC。Google Chrome 需要有共同合作的社群成員,才能推動 Chromium 專案。並非每位 Chromium 提交者都是 Google 員工,這些貢獻者值得特別表揚!