Copyright © 2015 the Contributors to the Web NFC API Specification, published by the Web NFC Community Group under the W3C Community Contributor License Agreement (CLA). A human-readable summary is available.
Near Field Communication (NFC) enables wireless communication between two devices at close proximity, usually less than a few centimeters. NFC is an international standard (ISO/IEC 18092) defining an interface and protocol for simple wireless interconnection of closely coupled devices operating at 13.56 MHz (see http://www.nfc-forum.org/specs/spec_list/).
This specification defines an API to manage selected NFC use-cases from web pages, and to enable new use-cases based on NFC technology.
This specification was published by the Web NFC Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.
Implementors need to be aware that this specification is considered unstable. Implementors who are not taking part in the discussions will find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should subscribe to the repository on GitHub and take part in the discussions.
Significant changes to this document since last publication are documented in the Changes section.
If you wish to make comments regarding this document, please send them to public-web-nfc@w3.org (subscribe, archives).
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, and SHOULD are to be interpreted as described in [RFC2119].
This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces it contains.
Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL], as this specification uses that specification and terminology.
The
EventHandler
interface represents a callback
used for event handlers as defined in [HTML5].
The concepts queue a task and fire a simple event are defined in [HTML5].
The terms event handler and event handler event types are defined in [HTML5].
Promise
, and
JSON.parse
are defined in [ECMASCRIPT].
The algorithms utf-8 encode, and utf-8 decode are defined in [ENCODING].
EventInit, DOMException, AbortError, SyntaxError, NotSupportedError, NotFoundError, and SecurityError are defined in [DOM4].
The term web app refers to a Web application, i.e. an application implemented using Web technologies, and executing within the context of a Web user agent, e.g. a Web browser or other Web-based runtime environments.
The term expressed permission refers to an act by the user, e.g. via user interface or host device platform features, via which the user approves the permission of a web app to access the Web NFC API.
The term obtain permission for a certain operation refers to obtain expressed permission or to ensure the existence of a prearranged trust relationship.
DOMString
,
ArrayBuffer
,
BufferSource
and
any
are defined in [WEBIDL].
NFC stands for Near Field Communications, short-range wireless technology operating at 13.56 MHz which enables communication between devices at a distance less than 10 cm. The NFC communications protocols and data exchange formats, and are based on existing radio-frequency identification (RFID) standards, including ISO/IEC 14443 and FeliCa. The NFC standards include ISO/IEC 18092[5] and those defined by the NFC Forum. See http://www.nfc-forum.org/specs/spec_list/ for a complete listing.
An NFC adapter is the software entity in the underlying platform which provides access to NFC functionality implemented in a given hardware element (NFC chip). A device may have multiple NFC adapters, for instance a built-in one, and one attached via USB.
An NFC tag is a passive, unpowered NFC device. The NFC tag is powered by magnetic induction when an active NFC device is in proximity range. An NFC tag contains a single NDEF message.
The way of reading the message may happen through proprietary technologies, which require the reader and the tag to be of the same manufacturer. Implementations are expected to encapsulate this.
An NFC peer is another device, which can interact with other devices in order to exchange data using NFC.
An NDEF message encapsulates one or more application-defined NDEF records. NDEF stands for NFC Forum Data Exchange Format, a lightweight binary message format. NDEF messages can be stored on a NFC tag or exchanged between NFC-enabled devices.
An NDEF record has a maximum payload of 2^32-1 bytes. The record also contains information about the payload size, type, and an optional identifier. NFC Forum standardized a small set of useful data types to be used in NDEF records, for instance text, URL, media. In addition, there are record types designed for more complex interactions, such as Smart Poster, and handover records.
Part of the NDEF record is the TNF field, standing for Type Name Format. It can take binary values representing the following types:
TNF value | NDEF record type |
---|---|
0 | Empty |
1 | NFC Forum Well-Known Type |
2 | Media Type |
3 | Absolute URI |
4 | NFC Forum External Type |
5 | Unknown |
6 | Unchanged |
7 | Reserved |
A Web NFC message is an NDEF message which contains at least one Web NFC record.
A Web NFC record is an NDEF record with TNF=4
(External Type Record), and the type field set to
"urn:nfc:ext:w3.org:webnfc"
. Further formatting details are
described Data Types.
An NFC handover defines NFC Forum Well Known Types and the corresponding message structure that allows negotiation and activation of an alternative communication carrier, such as Bluetooth or WiFi. The negotiated communication carrier would then be used (separately) to perform certain activities between the two devices, such as sending photos to the other device, printing to a Bluetooth printer or streaming video to a television set.
The term sufficient permission in this document means that a web app which is invoking the methods of this API has been checked to comply with the security policies set by the underlying platform and API implementation in the moment and context of invoking the API method. Further details are described in Security and Privacy.
The term document base URL is defined in [HTML5].
The term URL scope is introduced in this document for NFC operations as a sub-domain match to the web app's document URL, which includes the domain of the calling web app.
This section is non-normative.
There are three groups of user scenarios for NFC:
NFC works using magnetic induction, meaning that the reader will emit a small electric charge which then creates a magnetic field. This field powers the passive device which turns it into electrical impulses to communicate data. Thus, when the devices are within range, a read is always performed (see NFC Analog Specification and NFC Digital Protocol, NFC Forum, 2006). The peer-to-peer connection works in a similar way, as the device periodically switches into a so-called initiator mode in order to scan for targets, then later to fall back into target mode. If a target is found, the data is read the same way as for tags.
As NFC is based on existing RFID standards, many NFC chipsets support reading RFIDs tags, but many of these are only supported by single vendors and not part of the NFC standards. Though certain devices support reading and writing to these, it is not a goal of this specification to support proprietary tags or support interoperability with legacy systems.
The NFC Forum has mandated the support of four different tag types to be operable with NFC devices. The same is required on operating systems such as Android.
In addition to data types standardized for NDEF records by the NFC Forum, many commercial products, e.g. bus cards, door openers etc, use different card specific data and protocol extensions which require specific NFC chips (same vendor of card and reader) in order to work.
Card emulation mode capabilities also depend on the NFC chip in the device. For payments, a Secure Element is often needed.
This section is non-normative.
A few Web NFC user scenarios are described in this document. These user scenarios can be grouped along criteria based on security, privacy and feature categories, resulting in generic flows as follows.
In general, sending data to another Web NFC capable device requires that on the initiating device the user would first have to navigate to a web site. The user would then touch the device against another Web NFC equipped device, and data transfer would occur. On the receiving device the user agent will dispatch the content to a web site registered to handle the content and in case of multiple such web sites, the one chosen by the second user.
NFC supports handover protocols to Bluetooth or WiFi connectivity for the purpose of larger volume data transfer. The user touches another NFC capable device, and as a result configuration data is sent for a new Bluetooth or WiFi connection, which is then established between the devices.
High level features for the Web NFC specification include the following:
NFC is usually deeply integrated into device platforms (e.g. Android, Windows, etc), because end-to-end user experience implications (e.g. users need to be presented platform specific dialogs for selecting applications and actions). Also, privacy and security related issues require platform specific solutions.
The various integrated technologies, wide variety of use cases, and platform integration issues make standardization of NFC for the web a challenge. Therefore this specification makes a few simplifications in what use cases and data types are possible to handle by users of this API:
The following high level technical requirements result from the enumerated use cases and high level features. With this version of the API, web pages should be able to:
The Permissions API SHOULD
be supported by user agents for implementing NFC related
[permissions]. The required
permission name is "nfc"
.
User agents MUST NOT provide Web NFC API access to web apps without the expressed permission of the user. User agents must acquire consent for [permissions] for each call to the methods of this API, unless a prearranged trust relationship applies.
Considering adding the following: User agents MUST implement the WebNFC API to be HTTPS-only. SSL-only support provides better protection for the user against man-in-the-middle attacks intended to obtain push registration data. Browsers may ignore this rule for development purposes only.
Permissions that are preserved beyond the current browsing session MUST be revocable.
The Permissions API does not yet address the issue of revoking permissions. When it will be addressed, this section will be updated.
User agents MUST implement the following policies:
"https://"
SHOULD be able to read NFC tags that is
not empty or does not contain a Web NFC messages.
Web NFC implementations SHOULD use Web NFC messages, which SHOULD be sufficiently differentiated in order to avoid accidental matching with a generic NDEF message used in regular NFC tags or between NFC peers. This is achieved by using an additional Web NFC record, and in rest using normal NDEF records in order to compose the NDEF message.
The format of a Web NFC record is the following.
urn:nfc:ext:w3.org:webnfc
.
The payload of a Web NFC message is represented by using normal NDEF records. The following types can be used as payload, i.e. when writing to NFC tags, sending data to NFC peers, and when reading NDEF messages.
typedef (DOMString
or URL
or Blob
or JSON) NfcData;
NfcData denotes the data types supported as NDEF record payload in read and send operations in this API.
The mapping from supported NfcData
to
NDEF record types, as used in the
method is as follows:
send
()
NfcData | NDEF record type |
---|---|
DOMString | NFC Forum Well Known Type (TNF=1) with type Text |
URL | |
JSON | Media-type as defined in [RFC2046] (TNF=2) with associated
MIME type "application/json"
|
Blob with MIME type | Media-type as defined in [RFC2046] (TNF=2) |
Blob without MIME type | NFC Forum External Type (TNF=4) |
The mapping from NDEF record types to
,
as used for incoming NDEF messages exposed by the
NfcData
, is as follows:
NfcMessageEvent
NDEF record type | NfcData |
---|---|
NFC Forum Well Known Type (TNF=1) with type Text | DOMString |
NFC Forum Well Known Type (TNF=1) with type URI | URL object |
NFC Forum Well Known Type (TNF=1) with type Smart Poster | URL object |
Absolute URI as defined in [RFC3986] (TNF=3) | URL object |
Media-type as defined in [RFC2046] (TNF=2) with associated
MIME type "application/json"
|
JSON object |
Media-type as defined in [RFC2046] (TNF=2) | Blob object |
NFC Forum External Type (TNF=4) with type other than
urn:nfc:ext:w3.org:webnfc |
Blob object |
Any other NDEF record type | Blob object |
Note that Web NFC records are not exposed to client web apps.
interface Nfc {
Promise<NfcAdapter
> requestAdapter ();
};
Implementations MAY expose multiple NFC adapters. By using the requestAdapter() method, web apps can obtain an adapter object providing NFC functionality. When this method is invoked, the user agent MUST run the following steps:
Promise
object.
"SecurityError"
,
and terminate these steps.
"NotSupportedError"
, and terminate these steps.
"NotSupportedError"
, and terminate these steps.
null
."NotFoundError"
, and terminate these steps.
interface NfcAdapter : EventHandler
{
attribute EventHandler
onmessage;
Promise<void> send (NfcMessage
message, optional NfcSendOptions
options);
};
The NfcAdapter
interface handles incoming NDEF messages,
exposed by the
event, either from an
NFC tag or an NFC peer. By default, listening to this event
SHOULD be disabled.
NfcMessageEvent
The following are the event handlers implemented by the
interface.
NfcAdapter
event handler | event name | event type |
---|---|---|
onmessage |
message |
|
The message
event is used for notifying the adapter
object about an NDEF message dispatched to the web app.
In this specification, NDEF message content is delivered by an
NfcMessageEvent
event.
interface NfcMessageEvent : Event {
readonly attribute NfcMessage
message;
};
The message
property MUST return the
representing the
payload data of the NDEF message.
NfcMessage
The content of the NDEF message is exposed by the following interface:
[NoInterfaceObject]
interface NfcMessage {
readonly attribute USVString scope;
readonly attribute sequence<any
> data;
// (DOMString or URL or Blob or JSON)
};
The scope
property MUST return the URL scope which has written the message.
The
data
property MUST return the
payload data of the NDEF message as an array of either
DOMString
, or URL
object, or Blob
object, or serializable JSON object as a generic Object
.
The
send()
method is used for sending an NDEF message to
either an NFC tag for writing, or to an NFC peer device,
next time when they get into proximity range.
When this method is invoked, the user agent MUST run the following
steps:
Promise
object.
"SecurityError"
, and terminate these steps.
"NotSupportedError"
, and terminate these steps.
undefined
or null
, then use the default values.
Otherwise if invalid, then reject promise with
"SyntaxError"
, and terminate these steps.
undefined
, then set scope to
the DOMString
describing the document base URL.
If it is invalid in the given platform, or if it is not a
sub-domain match of the document base URL, then reject
promise with "SyntaxError"
, and terminate
these steps.
"SyntaxError"
, and
terminate these steps.
For each valid element create an NDEF record.
The implementation choose the best suitable NDEF record format
for the given platform.
Each element in the input array given in message.data
SHOULD map to a separate NDEF record in the NDEF message
to be sent.
"tag"
, then
the sending should only happen if an NFC tag is tapped within
a platform specific timeout, otherwise reject promise with
a "TimeoutError"
in the case of timeout, or
"InvalidAccessError"
if an NFC peer is
tapped instead of a tag.
"peer"
, then
the sending should only happen if an NFC peer is tapped within
a platform specific timeout, otherwise reject promise with
a "TimeoutError"
in the case of timeout, or
"InvalidAccessError"
if an NFC tag is
tapped instead of a peer.
"any"
(which
is the default value), then the sending should happen if either an
NFC peer or an NFC tag is tapped within a platform
specific timeout, otherwise reject promise with
"TimeoutError"
.
enum NfcTarget {
"tag",
"peer",
"any"
};
dictionary NfcSendOptions {
NfcTarget
target;
};
The target property
denotes the intended target for the pending send()
operation. The default value is "any"
.
This section is non-normative.
This section shows how developers can make use of the various features of this specification.
navigator.permissions.query({name: 'nfc'}).then((result) => { if (result.status == 'granted') { enableNfcUseCase(); // Do things here. } else if (result.status == 'prompt') { // The user agent will prompt. } // Otherwise don't do anything since it will fail. });
var adapter = null; navigator.nfc.requestAdapter().then((nfcAdapter) => { adapter = nfcAdapter; adapter.onmessage = onMessage; }; function onMessage(event) { console.log("NDEF message received from scope " + event.message.scope); var data = event.message.data; if (!data) { // empty tag writeMessageOnTag({data: “Initializing a passive tag”}); } if (typeof data == ‘string’) { console.log(“Data is string: “ + data); } else if (data instanceof Blob) { processBlob(data); } else if (data instanceof URL) { console.log(“Data is URL: “ + data.toString()); } else if (typeof data == ‘object’) { processJson(data); } }; function writeMessageOnTag(msg) { adapter.send(msg, {target: "tag"}) .then(() => { console.log("Send was successful")}) .catch(() => { console.log("Send failed")}); }; function processBlob(data) { console.log(“Blob size: ” + data.size + “ bytes”); console.log(“Blob type: ” + data.type); var reader = new FileReader(); reader.addEventListener(“loadend”, function() { console.log(“Blob data: ” + reader.result); // Now send a response based on the data. adapter.send({data: “Response to blob” }) .then(() => { console.log("Send was successful")}) .catch(() => { console.log("Send failed")}); }); reader.readAsText(data); }; function processJson(data) { if (myCondition(data.myKnownProperty)) { adapter.send({data: “Custom data”}); };
navigator.nfc.requestAdapter().then((adapter) => { console.log("Waiting for game state"); adapter.onmessage = (event) => { console.log("Game state received from: " + event.message.scope); console.log("Game state: " + event.message.data); // Now do some calculations and update the state. adapter.send({ scope: event.message.scope, data: [ { level: 3, points: 4500, lives: 3 } ] }) .then(() => { console.log("Send was successful")}) .catch(() => { console.log("Send failed")}); }; });
The following is a list of substantial changes to the document. For a complete list of changes, see the change log on Github. You can also view the recently closed bugs.
The following problems are being discussed and need most attention:
The editors would like to express their gratitude to the former editors Luc Yriarte and Samuel Ortiz, and also to Don Coleman, Jeffrey Yasskin, Salvatore Iovene, and Alexander Shalamov for their technical guidance, implementation feedback and support.