이제 NFC 태그를 읽고 쓸 수 있습니다.
Web NFC란 무엇인가요?
NFC는 근거리 무선 통신(Near Field Communications)의 약자로, 13.56MHz에서 작동하는 단거리 무선 기술로, 10cm 미만의 거리에서 기기 간 통신을 지원하며 최대 전송 속도는 424kbit/s입니다.
Web NFC를 사용하면 사이트가 사용자의 기기 (일반적으로 5~10cm)에 가까이 있을 때 NFC 태그를 읽고 쓸 수 있습니다. 현재 범위는 다양한 태그 형식에서 작동하는 경량 바이너리 메시지 형식인 NFC 데이터 교환 형식 (NDEF)으로 제한됩니다.

추천 사용 사례
NDEF 데이터의 읽기 및 쓰기 보안 속성을 더 쉽게 정량화할 수 있으므로 Web NFC는 NDEF로 제한됩니다. 하위 수준 I/O 작업 (예: ISO-DEP, NFC-A/B, NFC-F), 피어 투 피어 통신 모드, 호스트 기반 카드 에뮬레이션 (HCE)은 지원되지 않습니다.
Web 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 태그는 스티커, 신용카드, 손목 밴드 등 다양한 형태와 방식으로 제공됩니다.

NDEFReader
객체는 NDEF 태그가 근처에 있을 때 실행되는 읽기 또는 쓰기 작업을 준비하는 기능을 노출하는 Web NFC의 진입점입니다. NDEFReader
의 NDEF
는 NFC 포럼에서 표준화한 경량 바이너리 메시지 형식인 NFC 데이터 교환 형식을 나타냅니다.
NDEFReader
객체는 NFC 태그에서 수신되는 NDEF 메시지에 대해 작동하고 범위 내 NFC 태그에 NDEF 메시지를 쓰는 데 사용됩니다.
NDEF를 지원하는 NFC 태그는 포스트잇과 같습니다. 누구나 읽을 수 있으며 읽기 전용이 아닌 경우 누구나 쓸 수 있습니다. 하나 이상의 NDEF 레코드를 캡슐화하는 단일 NDEF 메시지가 포함되어 있습니다. 각 NDEF 레코드는 데이터 페이로드와 연결된 유형 정보를 포함하는 바이너리 구조입니다. Web NFC는 다음 NFC 포럼 표준화된 레코드 유형을 지원합니다. empty, text, URL, smart poster, MIME type, absolute URL, external type, unknown, local type

NFC 태그 스캔
NFC 태그를 스캔하려면 먼저 새 NDEFReader
객체를 인스턴스화합니다. scan()
를 호출하면 프로미스가 반환됩니다. 이전에 액세스 권한이 부여되지 않은 경우 사용자에게 메시지가 표시될 수 있습니다. 다음 조건이 모두 충족되면 프로미스가 해결됩니다.
- 터치 동작이나 마우스 클릭과 같은 사용자 동작에 대한 응답으로만 호출되었습니다.
- 사용자가 웹사이트가 NFC 기기와 상호작용하도록 허용했습니다.
- 사용자의 휴대전화가 NFC를 지원합니다.
- 사용자가 휴대전화에서 NFC를 사용 설정했습니다.
프로미스가 해결되면 이벤트 리스너를 통해 reading
이벤트를 구독하여 수신 NDEF 메시지를 사용할 수 있습니다. 호환되지 않는 NFC 태그가 근처에 있을 때 알림을 받으려면 readingerror
이벤트도 구독해야 합니다.
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
멤버는 데이터가 UTF-16으로 인코딩된 사례를 처리할 수 있으므로 DataView
로 노출됩니다.
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 태그에 URL 레코드를 쓰려면 NDEF 메시지를 나타내는 사전을 write()
에 전달합니다. 아래 예에서 NDEF 메시지는 records
키가 있는 사전입니다. 값은 레코드 배열입니다. 이 경우 recordType
키가 "url"
로 설정되고 data
키가 URL 문자열로 설정된 객체로 정의된 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}.`);
});
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()
는 Chrome 100 이상에서 Android에서 사용할 수 있으므로 다음을 사용하여 이 기능이 지원되는지 확인하세요.
if ("NDEFReader" in window && "makeReadOnly" in NDEFReader.prototype) {
// makeReadOnly() is supported.
}
보안 및 권한
Chrome팀은 사용자 제어, 투명성, 인체공학 등 강력한 웹 플랫폼 기능에 대한 액세스 제어에 정의된 핵심 원칙을 사용하여 Web NFC를 설계하고 구현했습니다.
NFC는 악성 웹사이트에서 사용할 수 있는 정보 도메인을 확장하므로 NFC 사용에 대한 사용자의 인지도와 제어력을 극대화하기 위해 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 콘텐츠 수신 및 푸시가 일시중지되며 웹페이지가 다시 표시되면 재개됩니다.
페이지 표시 상태 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.
}
};
설명서
다음은 시작하는 데 도움이 되는 몇 가지 코드 샘플입니다.
권한 확인
권한 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()
메서드의 옵션을 통해 AbortController
의 signal
를 전달하고 동시에 두 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 태그에서 새 메시지를 읽는 방법을 보여줍니다. 3초 후에 스캔이 중지됩니다.
// 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 레코드를 만들기 위한 전체 구문을 사용하여 두 속성 (encoding
및 lang
)을 모두 지정할 수 있습니다.
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] });
URL 레코드 읽기 및 쓰기
TextDecoder
을 사용하여 레코드의 data
을 디코딩합니다.
function readUrlRecord(record) {
console.assert(record.recordType === "url");
const textDecoder = new TextDecoder();
console.log(`URL: ${textDecoder.decode(record.data)}`);
}
URL 레코드를 작성하려면 NDEF 메시지 사전을 NDEFReader write()
메서드에 전달합니다. NDEF 메시지에 포함된 URL 레코드는 recordType
키가 "url"
로 설정되고 data
키가 URL 문자열로 설정된 객체로 정의됩니다.
const urlRecord = {
recordType: "url",
data:"https://w3c.github.io/web-nfc/"
};
const ndef = new NDEFReader();
await ndef.write({ records: [urlRecord] });
MIME 유형 레코드 읽기 및 쓰기
MIME 유형 레코드의 mediaType
속성은 data
이 올바르게 디코딩될 수 있도록 NDEF 레코드 페이로드의 MIME 유형을 나타냅니다. 예를 들어 JSON.parse
를 사용하여 JSON 텍스트를 디코딩하고 이미지 요소를 사용하여 이미지 데이터를 디코딩합니다.
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
에 대한 뷰를 제공하는 객체 (예: 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] });
절대 URL 레코드 읽기 및 쓰기
절대 URL 레코드 data
는 간단한 TextDecoder
로 디코딩할 수 있습니다.
function readAbsoluteUrlRecord(record) {
console.assert(record.recordType === "absolute-url");
const textDecoder = new TextDecoder();
console.log(`Absolute URL: ${textDecoder.decode(record.data)}`);
}
절대 URL 레코드를 작성하려면 NDEF 메시지 사전을 NDEFReader write()
메서드에 전달합니다. NDEF 메시지에 포함된 절대 URL 레코드는 recordType
키가 "absolute-url"
로 설정되고 data
키가 URL 문자열로 설정된 객체로 정의됩니다.
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
을 스마트 포스터 레코드에 포함된 레코드 목록으로 변환합니다. URL 레코드, 제목의 텍스트 레코드, 이미지의 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 메시지가 페이로드로 포함될 수 있습니다. 이름에는 발급 조직의 도메인 이름, 콜론, 1자 이상의 유형 이름이 포함됩니다(예: "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
에 대한 뷰를 제공할 수도 있습니다 (예: 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] });
빈 레코드 읽기 및 쓰기
빈 레코드에는 페이로드가 없습니다.
빈 레코드를 작성하려면 NDEF 메시지 사전을 NDEFReader write()
메서드에 전달합니다. NDEF 메시지에 포함된 빈 레코드는 recordType
키가 "empty"
로 설정된 객체로 정의됩니다.
const emptyRecord = {
recordType: "empty"
};
const ndef = new NDEFReader();
await ndef.write({ records: [emptyRecord] });
브라우저 지원
웹 NFC는 Chrome 89의 Android에서 사용할 수 있습니다.
개발자 팁
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 데모를 확인하세요.
의견
Web NFC 커뮤니티 그룹과 Chrome팀은 Web NFC에 관한 여러분의 생각과 경험을 듣고 싶습니다.
API 설계에 대해 알려주세요.
API가 예상대로 작동하지 않는 부분이 있나요? 아이디어를 구현하는 데 필요한 메서드나 속성이 누락되어 있나요?
Web NFC GitHub 저장소에 사양 문제를 제출하거나 기존 문제에 의견을 추가하세요.
구현 문제 신고
Chrome 구현에서 버그를 발견하셨나요? 아니면 구현이 사양과 다른가요?
https://new.crbug.com에서 버그를 신고하세요. 가능한 한 많은 세부정보를 포함하고, 버그를 재현하는 간단한 안내를 제공하고, 구성요소를 Blink>NFC
로 설정하세요.
지원 표시
Web NFC를 사용할 계획인가요? 공개적인 지원은 Chrome팀이 기능의 우선순위를 정하는 데 도움이 되며 다른 브라우저 공급업체에 이러한 기능을 지원하는 것이 얼마나 중요한지 보여줍니다.
#WebNFC
해시태그를 사용하여 @ChromiumDev에 트윗을 보내 어디에서 어떻게 사용하고 있는지 알려주세요.
유용한 링크
- 사양
- Web NFC 데모
- 버그 추적
- ChromeStatus.com 항목
- Blink 구성요소:
Blink>NFC
감사의 말씀
Web NFC를 구현해 주신 Intel 여러분께 감사드립니다. Google Chrome은 Chromium 프로젝트를 발전시키기 위해 함께 노력하는 커미터 커뮤니티에 의존합니다. 모든 Chromium 커밋터가 Google 직원은 아니며 이러한 기여자는 특별한 인정을 받아야 합니다.