עכשיו אפשר לקרוא ולכתוב תגי NFC.
מהו Web NFC?
NFC הוא ראשי תיבות של Near Field Communications (תקשורת מטווח קצר), טכנולוגיה אלחוטית לטווח קצר שפועלת בתדר 13.56MHz ומאפשרת תקשורת בין מכשירים במרחק של פחות מ-10 ס"מ ובקצב העברה של עד 424kbit/s.
Web NFC מאפשר לאתרים לקרוא ולכתוב לתגי NFC כשהם נמצאים בקרבה למכשיר של המשתמש (בדרך כלל 5-10 ס"מ). ההיקף הנוכחי מוגבל לפורמט חילופי נתונים של NFC (NDEF), פורמט הודעות בינארי קל משקל שפועל בפורמטים שונים של תגים.

תרחישים לדוגמה
השימוש ב-Web NFC מוגבל ל-NDEF כי קל יותר לכמת את מאפייני האבטחה של קריאה וכתיבה של נתוני NDEF. אין תמיכה בפעולות קלט/פלט ברמה נמוכה (למשל, 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, פורמט קל של הודעות בינאריות שעבר סטנדרטיזציה על ידי NFC Forum.
אובייקט NDEFReader
מיועד לפעולה על הודעות NDEF נכנסות מתגי NFC ולכתיבת הודעות NDEF בתגי NFC בטווח.
תג NFC שתומך ב-NDEF הוא כמו פתק דביק. כל אחד יכול לקרוא אותו, ואם הוא לא לקריאה בלבד, כל אחד יכול לכתוב בו. הוא מכיל הודעת NDEF אחת שמכילה רשומת NDEF אחת או יותר. כל רשומה של NDEF היא מבנה בינארי שמכיל מטען נתונים ומידע על הסוג המשויך. Web NFC תומך בסוגי הרשומות הבאים שתוקננו על ידי NFC Forum: ריק, טקסט, כתובת URL, פוסטר חכם, סוג MIME, כתובת URL מוחלטת, סוג חיצוני, לא ידוע וסוג מקומי.

סריקת תגי NFC
כדי לסרוק תגי NFC, קודם יוצרים מופע חדש של אובייקט NDEFReader
. התקשרות אל scan()
מחזירה הבטחה. יכול להיות שהמשתמש יתבקש לאשר את הגישה אם הוא לא אישר אותה בעבר. ההבטחה תמומש אם כל התנאים הבאים יתקיימו:
- הפונקציה נקראה רק בתגובה למחווה של משתמש, כמו מחווה של מגע או לחיצה על העכבר.
- המשתמש נתן לאתר הרשאה ליצור אינטראקציה עם מכשירי NFC.
- הטלפון של המשתמש תומך ב-NFC.
- המשתמש הפעיל NFC בטלפון שלו.
אחרי שההבטחה מתקיימת, הודעות NDEF נכנסות זמינות באמצעות הרשמה לאירועי reading
דרך פונקציית event 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
. הוא כולל שני מאפיינים ייחודיים:
-
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 והתג הפך לקריאה בלבד.
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 בגרסה 100 של Chrome ואילך. כדי לבדוק אם התכונה נתמכת, אפשר:
if ("NDEFReader" in window && "makeReadOnly" in NDEFReader.prototype) {
// makeReadOnly() is supported.
}
אבטחה והרשאות
צוות Chrome תכנן והטמיע את Web NFC על סמך העקרונות המרכזיים שמוגדרים במאמר שליטה בגישה לתכונות עוצמתיות של פלטפורמת האינטרנט, כולל שליטה של המשתמש, שקיפות וארגונומיה.
מכיוון ש-NFC מרחיב את תחום המידע שעשוי להיות זמין לאתרים זדוניים, הזמינות של NFC מוגבלת כדי למקסם את המודעות של המשתמשים ואת השליטה שלהם בשימוש ב-NFC.

ה-API של 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. בדוגמה הבאה אפשר לראות איך מעבירים את signal
של AbortController
דרך האפשרויות של השיטות NDEFReader scan()
, makeReadOnly()
, write()
ומבטלים את שתי פעולות ה-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
באמצעות מופע 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 כברירת מחדל, והן מניחות את השפה של המסמך הנוכחי, אבל אפשר לציין את שני המאפיינים (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
כדי לפענח את data
של הרשומה, משתמשים ב-TextDecoder
.
function readUrlRecord(record) {
console.assert(record.recordType === "url");
const textDecoder = new TextDecoder();
console.log(`URL: ${textDecoder.decode(record.data)}`);
}
כדי לכתוב רשומת URL, מעבירים מילון הודעות NDEF ל-method 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 של מטען הייעודי (payload) של רשומת NDEF, כדי שניתן יהיה לפענח את 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()
. רשומת סוג ה-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 לשיטה NDEFReader write()
. רשומה של כתובת 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 כמטען ייעודי (payload). תתקשר אל 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] });
קריאה וכתיבה של רשומה מסוג חיצוני
כדי ליצור רשומות שמוגדרות על ידי האפליקציה, צריך להשתמש ברשומות מסוג חיצוני. יכול להיות שהם יכילו הודעת NDEF כמטען ייעודי (payload) שאפשר לגשת אליו באמצעות 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 לשיטה 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] });
קריאה וכתיבה של רשומה ריקה
רשומה ריקה לא מכילה מטען ייעודי (payload).
כדי לכתוב רשומה ריקה, מעבירים מילון של הודעת NDEF לשיטה NDEFReader
write()
. הרשומה הריקה שכלולה בהודעת NDEF מוגדרת כאובייקט עם מפתח recordType
שהערך שלו הוא "empty"
.
const emptyRecord = {
recordType: "empty"
};
const ndef = new NDEFReader();
await ndef.write({ records: [emptyRecord] });
תמיכה בדפדפנים
Web 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 וצוות Chrome ישמחו לשמוע את דעתכם על Web NFC וללמוד על הניסיון שלכם איתה.
נשמח לקבל מידע על עיצוב ה-API
האם יש משהו ב-API שלא פועל כמו שציפית? או שיש שיטות או מאפיינים חסרים שצריך להטמיע כדי ליישם את הרעיון?
אפשר לפתוח בעיה במפרט במאגר Web NFC GitHub או להוסיף את המחשבות שלכם לבעיה קיימת.
דיווח על בעיה בהטמעה
מצאתם באג בהטמעה של Chrome? או שההטמעה שונה מהמפרט?
מדווחים על באג בכתובת https://new.crbug.com. חשוב לכלול כמה שיותר פרטים, לספק הוראות פשוטות לשחזור הבאג ולוודא שהמרכיבים מוגדרים לערך Blink>NFC
.
תמיכה ביוצרים
האם בכוונתך להשתמש ב-Web NFC? התמיכה הציבורית שלכם עוזרת לצוות Chrome לתת עדיפות לתכונות, ומראה לספקי דפדפנים אחרים עד כמה חשוב לתמוך בהן.
אתם יכולים לשלוח ציוץ אל @ChromiumDev באמצעות ההאשטאג
#WebNFC
ולספר לנו איפה ואיך אתם משתמשים בו.
קישורים שימושיים
- מפרט
- Web NFC Demo
- באג במעקב
- ערך ב-ChromeStatus.com
- רכיב Blink:
Blink>NFC
תודות
תודה רבה לצוות Intel על הטמעת Web NFC. Google Chrome תלוי בקהילה של משתתפים שפועלים יחד כדי לקדם את פרויקט Chromium. לא כל מי ששולח קוד ל-Chromium הוא עובד Google, ולתורמים האלה מגיעה הכרה מיוחדת!