อ่านและเขียนแท็ก NFC ได้แล้ว
Web NFC คืออะไร
NFC ย่อมาจาก Near Field Communications ซึ่งเป็นเทคโนโลยีไร้สายระยะสั้นที่ทำงานที่ 13.56 MHz ซึ่งช่วยให้สามารถสื่อสารระหว่างอุปกรณ์ ที่มีระยะสัญญาณน้อยกว่า 10 ซม. และอัตราการส่งผ่านสูงสุดถึง 424 kbit/s
NFC บนเว็บทำให้เว็บไซต์สามารถอ่านและเขียนแท็ก NFC เมื่ออยู่ใกล้กับอุปกรณ์ของผู้ใช้ (โดยปกติจะมีขนาด 5-10 ซม. หรือ 2-4 นิ้ว) ขอบเขตปัจจุบันจำกัดอยู่ที่รูปแบบ NFC Data Exchange (NDEF) ซึ่งเป็นรูปแบบข้อความไบนารีขนาดเล็กที่ทำงานได้ในแท็กรูปแบบต่างๆ
กรณีการใช้งานที่แนะนำ
Web NFC จำกัดไว้เฉพาะสำหรับ NDEF เนื่องจากคุณสมบัติด้านความปลอดภัยของการอ่านและการเขียนข้อมูล 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
เป็นจุดแรกเข้าใน Web NFC ที่แสดงฟังก์ชันสำหรับเตรียมการดำเนินการอ่านและ/หรือเขียนที่เสร็จสมบูรณ์เมื่อแท็ก NDEF เข้ามาใกล้กัน NDEF
ใน NDEFReader
ย่อมาจาก NFC Data Exchange Format ซึ่งเป็นรูปแบบข้อความไบนารีขนาดเล็กที่ฟอรัม NFC เป็นมาตรฐาน
ออบเจ็กต์ NDEFReader
มีไว้เพื่อดำเนินการกับข้อความ NDEF ขาเข้าจากแท็ก NFC และเขียนข้อความ NDEF ไปยังแท็ก NFC ภายในช่วง
แท็ก NFC ที่รองรับ NDEF เป็นเหมือนโน้ตโพสต์อิต ทุกคนสามารถอ่านได้ ยกเว้นการเขียนแบบอ่านอย่างเดียว ซึ่งประกอบด้วยข้อความ NDEF เดียว ที่สรุประเบียน NDEF อย่างน้อย 1 รายการ ระเบียน NDEF แต่ละรายการเป็นโครงสร้างไบนารีที่มีเพย์โหลดข้อมูล และข้อมูลประเภทที่เกี่ยวข้อง เว็บ NFC รองรับประเภทระเบียนตามมาตรฐานของฟอรัม NFC ต่อไปนี้ ว่าง, ข้อความ, URL, โปสเตอร์อัจฉริยะ, ประเภท MIME, URL ที่สมบูรณ์, ประเภทภายนอก, ไม่รู้จัก และประเภทในเครื่อง
สแกนแท็ก NFC
หากต้องการสแกนแท็ก NFC ให้สร้างอินสแตนซ์ NDEFReader
ใหม่ก่อน การโทรเรียก scan()
จะให้ผลลัพธ์ ผู้ใช้อาจได้รับข้อความแจ้งหากไม่เคยได้รับสิทธิ์ในการเข้าถึงมาก่อน สัญญาจะสิ้นสุดหากเป็นไปตามเงื่อนไขต่อไปนี้ทั้งหมด
- โดยมีการเรียกเฉพาะการตอบสนองต่อท่าทางสัมผัสของผู้ใช้ เช่น ท่าทางสัมผัสการแตะ หรือการคลิกเมาส์
- ผู้ใช้อนุญาตให้เว็บไซต์โต้ตอบกับอุปกรณ์ NFC
- โทรศัพท์ของผู้ใช้รองรับ NFC
- ผู้ใช้ได้เปิดใช้ NFC ในโทรศัพท์ของตน
เมื่อแก้ปัญหาแล้ว ข้อความ NDEF ที่เข้ามาใหม่จะพร้อมใช้งานโดยการสมัครรับข้อมูลกิจกรรม reading
ผ่าน Listener เหตุการณ์ นอกจากนี้ คุณควรสมัครรับข้อมูลเหตุการณ์ 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
จะเริ่มทำงาน ซึ่งมีพร็อพเพอร์ตี้ 2 รายการต่อไปนี้
serialNumber
แสดงหมายเลขซีเรียลของอุปกรณ์ (เช่น 00-11-22-33-44-55-66) หรือสตริงว่างหากไม่มีข้อมูลmessage
แสดงข้อความ NDEF ที่จัดเก็บไว้ในแท็ก NFC
หากต้องการอ่านเนื้อหาของข้อความ NDEF ให้วนซ้ำ message.records
และประมวลผลสมาชิก data
คนอย่างเหมาะสมตามrecordType
สมาชิก 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}.`);
});
หากต้องการเขียนระเบียน URL ไปยังแท็ก NFC ให้ส่งพจนานุกรมที่แสดงถึงข้อความ NDEF ไปยัง write()
ในตัวอย่างด้านล่าง ข้อความ NDEF เป็นพจนานุกรมที่มีคีย์ records
ค่าของระเบียนคืออาร์เรย์ของระเบียน ในกรณีนี้ ระเบียน URL ที่กำหนดเป็นออบเจ็กต์ที่ตั้งค่าคีย์ recordType
เป็น "url"
และชุดคีย์ data
เป็นสตริง 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 ที่ไม่ได้มีไว้เพื่อเขียนทับ ให้ตั้งค่าพร็อพเพอร์ตี้ overwrite
เป็น false
ในตัวเลือกที่ส่งไปยังเมธอด write()
ในกรณีดังกล่าว สัญญาที่แสดงผลจะปฏิเสธหากมีข้อความ NDEF เก็บไว้ในแท็ก 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}.`);
});
กำหนดให้แท็ก 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 ใช้งานได้กับเฟรมระดับบนสุดและบริบทการท่องเว็บอย่างปลอดภัยเท่านั้น (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.
}
};
ตำราอาหาร
นี่คือตัวอย่างโค้ดบางส่วนที่จะช่วยคุณเริ่มต้น
ตรวจสอบสิทธิ์
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 ได้ง่าย ตัวอย่างด้านล่างแสดงวิธีส่ง signal
ของ AbortController
ผ่านตัวเลือกเมธอด NDEFReader scan()
, makeReadOnly()
, write()
และล้มเลิกการดำเนินการของ NFC ทั้ง 2 รายการพร้อมกัน
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 และอ่านข้อความใหม่ในแท็ก 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
ได้ด้วยอินสแตนซ์ TextDecoder
ที่มีพร็อพเพอร์ตี้ encoding
ของระเบียน โปรดทราบว่าภาษาของระเบียนข้อความจะใช้ได้ผ่านพร็อพเพอร์ตี้ lang
function readTextRecord(record) {
console.assert(record.recordType === "text");
const textDecoder = new TextDecoder(record.encoding);
console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
}
หากต้องการเขียนระเบียนข้อความแบบง่าย ให้ส่งสตริงไปยังเมธอด write()
ของ NDEFReader
const ndef = new NDEFReader();
await ndef.write("Hello World");
ระเบียนข้อความจะเป็น UTF-8 โดยค่าเริ่มต้น และจะถือว่าเป็นภาษาของเอกสารปัจจุบัน แต่สามารถระบุพร็อพเพอร์ตี้ทั้ง 2 รายการ (encoding
และ lang
) ได้โดยใช้ไวยากรณ์แบบเต็มสำหรับการสร้างระเบียน 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] });
อ่านและเขียนระเบียน 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()
ระเบียน URL ที่อยู่ในข้อความ NDEF กำหนดเป็นออบเจ็กต์ที่มีการตั้งค่าคีย์ 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
พร็อพเพอร์ตี้ mediaType
ของระเบียนประเภท MIME แสดงถึงประเภท MIME ของเพย์โหลดระเบียน NDEF เพื่อให้ถอดรหัส data
ได้อย่างถูกต้อง เช่น ใช้ 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()
ระเบียนประเภท MIME ที่มีอยู่ในข้อความ NDEF คือออบเจ็กต์ที่ตั้งค่าคีย์ 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 ไปยังเมธอด write()
ของ NDEFReader ระเบียน URL สัมบูรณ์ที่อยู่ในข้อความ NDEF ได้รับการกำหนดเป็นออบเจ็กต์ที่ตั้งค่าคีย์ 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 ไปยังเมธอด write()
ของ NDEFReader ระเบียนโปสเตอร์อัจฉริยะที่มีอยู่ในข้อความ NDEF นั้นกำหนดเป็นออบเจ็กต์ที่ตั้งค่าคีย์ recordType
เป็น "smart-poster"
และตั้งค่าคีย์ data
เป็นออบเจ็กต์ที่แสดงถึงข้อความ NDEF ที่อยู่ในระเบียน Smart Post (อีกครั้ง)
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()
ชื่อของพวกเขามีชื่อโดเมนขององค์กรที่ออก โคลอน และชื่อประเภทที่มีความยาวอย่างน้อย 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 ไปยังเมธอด write()
ของ NDEFReader ระเบียนประเภทภายนอกที่มีอยู่ในข้อความ 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 ใช้งานได้บน Android ใน Chrome 89
เคล็ดลับสำหรับนักพัฒนา
นี่คือรายการสิ่งที่ฉันอยากทราบตอนที่เริ่มเล่น Web NFC
- โดย Android จะจัดการแท็ก NFC ที่ระดับระบบปฏิบัติการก่อนที่ Web NFC จะทำงาน
- คุณจะเห็นไอคอน NFC ใน material.io
- ใช้ระเบียน NDEF
id
เพื่อระบุระเบียนได้อย่างง่ายดายเมื่อจำเป็น - แท็ก NFC ที่ไม่ได้จัดรูปแบบซึ่งรองรับ NDEF จะมีระเบียนประเภทว่างอยู่รายการเดียว
- การเขียนระเบียนแอปพลิเคชัน 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 Community Group และทีม Chrome ต้องการทราบความคิดเห็นและประสบการณ์การใช้งาน Web NFC ของคุณ
บอกให้เราทราบเกี่ยวกับการออกแบบ API
มีบางอย่างเกี่ยวกับ API ที่ทำงานไม่ได้ตามที่คาดไว้ไหม หรือมีวิธีหรือคุณสมบัติที่ขาดหายไปที่คุณจำเป็นต้องใช้ในการนำแนวคิดของคุณไปปรับใช้
โปรดแจ้งปัญหาเกี่ยวกับข้อมูลจำเพาะในที่เก็บ GitHub ของเว็บ NFC หรือแสดงความคิดเห็นเกี่ยวกับปัญหาที่มีอยู่
รายงานปัญหาเกี่ยวกับการใช้งาน
คุณพบข้อบกพร่องในการใช้งาน Chrome หรือไม่ หรือการใช้งานแตกต่างจาก ข้อกำหนดหรือไม่
รายงานข้อบกพร่องที่ https://new.crbug.com อย่าลืมระบุรายละเอียดให้มากที่สุดเท่าที่จะทำได้ ระบุวิธีการง่ายๆ ในการสร้างข้อบกพร่องอีกครั้ง และตั้งค่าคอมโพเนนต์เป็น Blink>NFC
Glitch เหมาะสำหรับการแชร์
การเรียกซ้ำที่ง่ายและรวดเร็ว
แสดงการสนับสนุน
คุณวางแผนที่จะใช้ Web NFC หรือไม่ การสนับสนุนสาธารณะของคุณช่วยให้ทีม Chrome จัดลำดับความสำคัญของคุณลักษณะต่างๆ และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นๆ เห็นว่าการสนับสนุนนั้นสำคัญเพียงใด
ส่งทวีตไปที่ @ChromiumDev โดยใช้แฮชแท็ก
#WebNFC
และแจ้งให้เราทราบว่าคุณใช้แฮชแท็กนี้ที่ไหนและอย่างไร
ลิงก์ที่มีประโยชน์
- ข้อกำหนด
- การสาธิต NFC ในเว็บ | แหล่งที่มาการสาธิต NFC ในเว็บ
- ข้อบกพร่องในการติดตาม
- รายการ ChromeStatus.com
- คอมโพเนนต์การกะพริบ:
Blink>NFC
ข้อความแสดงการยอมรับ
ขอขอบคุณอย่างยิ่งสำหรับทีมงาน Intel ที่นำ Web NFC มาใช้งาน Google Chrome อาศัยชุมชนคณะกรรมการที่ทำงานร่วมกันเพื่อผลักดันโครงการ Chromium ให้ก้าวไปข้างหน้า ไม่ใช่ทุกคนของ Chromium ที่จะเป็น Googler และผู้มีส่วนร่วม เหล่านี้สมควรได้รับการยกย่องชมเชยเป็นพิเศษ!