在 Android 版 Google Chrome 與 NFC 裝置互動

現在可以讀取及寫入 NFC 標記。

François Beaufort
François Beaufort

什麼是 Web NFC?

NFC 是近距離無線通訊技術,運作頻率為 13.56 MHz,可讓裝置在 10 公分以內的距離通訊,傳輸速率最高可達 424 kbit/s。

Web 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,但無法判斷是否具備必要硬體。特別是如果缺少硬體,特定呼叫傳回的 Promise 會遭到拒絕。我會在說明 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 論壇標準化記錄類型:空白、文字、網址、智慧海報、MIME 類型、絕對網址、外部類型、不明和本機類型。

NDEF 訊息圖
NDEF 訊息圖表

掃描 NFC 標記

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

  • 只有在使用者做出手勢 (例如觸控手勢) 或點按滑鼠時,才會呼叫這個函式。
  • 使用者已允許網站與 NFC 裝置互動。
  • 使用者的手機支援 NFC。
  • 使用者已在手機上啟用 NFC。

Promise 解決後,只要透過事件監聽器訂閱 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() 會傳回 promise。如果先前未授予存取權,系統可能會提示使用者。此時,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 訊息,傳回的 Promise 會遭到拒絕。

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() 會傳回 promise。如果先前未授予存取權,系統可能會提示使用者。如果符合下列所有條件,這個 Promise 就會解決:

  • 只有在使用者做出手勢 (例如觸控手勢) 或點按滑鼠時,才會呼叫這個函式。
  • 使用者已允許網站與 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}`);
}

Chrome 100 以上版本已在 Android 裝置上推出 makeReadOnly(),請按照下列步驟確認是否支援這項功能:

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" permission。如果先前未授予存取權,NDEFReaderscan()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(),然後搭配 AbortController 基本體使用 scan(),即可在將訊息寫入 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,並採用目前文件的語言,但可以使用完整語法建立自訂 NDEF 記錄,指定這兩項屬性 (encodinglang)。

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

讀取及寫入外部型別記錄

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

瀏覽器支援

Chrome 89 版的 Android 裝置支援 Web NFC。

開發提示

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

  • Android 會在 Web NFC 運作前,在 OS 層級處理 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 回報錯誤。請務必盡可能提供詳細資料,並提供重現錯誤的簡單操作說明,且將「Components」設為 Blink>NFC

顯示支援

您是否打算使用 Web NFC?您的公開支持有助於 Chrome 團隊優先處理功能,並向其他瀏覽器供應商展現支援這些功能的重要性。

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

實用連結

特別銘謝

非常感謝 Intel 團隊實作 Web NFC。Google Chrome 仰賴提交者社群的共同努力,推動 Chromium 專案。並非所有 Chromium 提交者都是 Google 員工,這些貢獻者值得特別表揚!