Теперь возможно чтение и запись тегов NFC.
Что такое веб-NFC?
NFC означает Near Field Communications, беспроводную технологию ближнего действия, работающую на частоте 13,56 МГц, которая обеспечивает связь между устройствами на расстоянии менее 10 см и скоростью передачи до 424 кбит/с.
Web NFC предоставляет сайтам возможность считывать и записывать теги NFC, когда они находятся в непосредственной близости от устройства пользователя (обычно 5–10 см, 2–4 дюйма). Текущая область применения ограничена форматом обмена данными NFC (NDEF), облегченным форматом двоичных сообщений, который работает с различными форматами тегов.
Рекомендуемые варианты использования
Web NFC ограничен NDEF, поскольку свойства безопасности чтения и записи данных NDEF легче поддаются количественной оценке. Операции ввода-вывода низкого уровня (например, ISO-DEP, NFC-A/B, NFC-F), режим одноранговой связи и эмуляция карты на основе хоста (HCE) не поддерживаются.
Примеры сайтов, которые могут использовать Web NFC:
- Музеи и художественные галереи могут отображать дополнительную информацию о дисплее, когда пользователь прикасается своим устройством к NFC-карте рядом с экспонатом.
- Сайты управления запасами могут считывать или записывать данные в тег NFC на контейнере для обновления информации о его содержимом.
- Сайты конференции могут использовать его для сканирования бейджей NFC во время мероприятия и убедиться, что они заблокированы, чтобы предотвратить дальнейшие изменения написанной на них информации.
- Сайты могут использовать его для обмена исходными секретами, необходимыми для сценариев предоставления устройств или услуг, а также для развертывания данных конфигурации в рабочем режиме.
Текущий статус
Шаг | Статус |
---|---|
1. Создайте объяснитель | Полный |
2. Создайте первоначальный проект спецификации. | Полный |
3. Соберите отзывы и доработайте дизайн | Полный |
4. Пробная версия происхождения | Полный |
5. Запуск | Полный |
Используйте веб-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
через прослушиватель событий. Вам также следует подписаться на события 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, передайте в write()
словарь, который представляет сообщение NDEF. В приведенном ниже примере сообщение 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.
Веб-NFC доступен только для кадров верхнего уровня и контекстов безопасного просмотра (только HTTPS). Origins должен сначала запросить разрешение "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 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.
}
};
Поваренная книга
Вот несколько примеров кода, которые помогут вам начать.
Проверьте разрешение
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-записи
Используйте TextDecoder
для декодирования data
записи.
function readUrlRecord(record) {
console.assert(record.recordType === "url");
const textDecoder = new TextDecoder();
console.log(`URL: ${textDecoder.decode(record.data)}`);
}
Чтобы записать запись URL-адреса, передайте словарь сообщений NDEF методу write()
NDEFReader. Запись 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 и элемент 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 методу write()
NDEFReader. Запись типа 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-адреса
data
записи абсолютного URL-адреса можно декодировать с помощью простого 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, содержащееся в записи интеллектуального плаката.
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 методу 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 методу write()
NDEFReader. Пустая запись, содержащаяся в сообщении 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 .
- Используйте
id
записи NDEF, чтобы при необходимости легко идентифицировать запись. - Неформатированный тег 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
. Glitch отлично подходит для быстрого и простого обмена репродукциями.
Показать поддержку
Планируете ли вы использовать Web NFC? Ваша публичная поддержка помогает команде Chrome расставлять приоритеты в функциях и показывает другим поставщикам браузеров, насколько важно их поддерживать.
Отправьте твит @ChromiumDev , используя хэштег #WebNFC
, и сообщите нам, где и как вы его используете.
Полезные ссылки
- Спецификация
- Веб-демонстрация NFC | Источник веб-демонстрации NFC
- Ошибка отслеживания
- Запись ChromeStatus.com
- Компонент мигания:
Blink>NFC
Благодарности
Большое спасибо ребятам из Intel за внедрение Web NFC. Google Chrome зависит от сообщества коммиттеров, работающих вместе над продвижением проекта Chromium. Не каждый коммиттер Chromium является сотрудником Google, и эти участники заслуживают особого признания!