This specification defines an API that allows websites to declare
themselves as web share targets, which can receive shared
content from either the Web Share API, or
system events (e.g., shares from native apps).
This is a similar mechanism to navigator.registerProtocolHandler,
in that it works by registering the website with the user agent, to
later be invoked from another site or native application via the
user agent (possibly at the discretion of the user). The difference is
that registerProtocolHandler
registers the handler via a programmatic API, whereas a Web Share
Target is declared in the Web App
Manifest, to be registered at a time of the user agent or user's
choosing.
Status of This Document
This is a
preview
Do not attempt to implement this version of the specification. Do
not reference this version as authoritative in any way.
Instead, see
https://wicg.github.io/web-share-target/level-2/ for the
Editor's draft.
In order to implement this API, it is REQUIRED that the user agent
implements Web App Manifest. This spec
also re-uses some definitions from the Web
Share API spec. Implementation of that spec is NOT REQUIRED to
implement this one (but it is RECOMMENDED).
The params keys correspond to the
key names in ShareData from
[WebShare], while the values are arbitrary names that will be used as
query parameters when the target is launched.
When a share takes place, if the user selects this share target, the
user agent opens a new browsing context at the action URL,
with query parameter values containing the shared data, just like an
HTML form submission.
For the purpose of this example, we assume the manifest is located at
https://example.org/includinator/manifest.webmanifest.
U+0020 (SPACE) characters are encoded as "+", due to the
use of application/x-www-form-urlencoded
encoding, not "%20" as might be expected. Processors must
take care to decode U+002B (+) characters as U+0020 (SPACE), which some
URL decoding libraries, including ECMAScript's decodeURIComponent
function, may not do automatically.
The query parameters are populated with information from the
ShareData being
shared. If the ShareData contains no information for a given member,
the query parameter is omitted.
A share target might only be interested in a subset of the
ShareData members. This
example also shows a share target that receives data as a
POST request, which should be the case if the request
causes an immediate side effect.
The target will be invoked with a
multipart/form-data POST request, with field names as
specified in params. Each shared file is assigned to the first files
entry that accepts its MIME type. (The "POST"method and "multipart/form-data"enctype are necessary when file sharing, as with HTML
forms.)
How the handler deals with the shared data is at the handler's
discretion, and will generally depend on the type of app. Here are some
suggestions:
An email client might draft a new email, using title
as the subject of an email, with text and url
concatenated together as the body, and files as
attachments.
A social networking app might draft a new post, ignoring
title, using text as the body of the message
and adding url as a link. Image files would
be accepted by MIME type or file extension, and attached to the post.
If text is missing, it might use url in the
body as well. If url is missing, it might scan
text looking for a URL and add that as a link.
A text messaging app might draft a new message, ignoring
title and using text and url
concatenated together. It might truncate the text or replace
url with a short link to fit into the message size.
As with HTML forms, replying to a POST request with a 303 See Other redirect is highly
recommended, as it avoids the POST being submitted a second time if the
user requests a page refresh.
3.
Extension to the Web App Manifest
The following IDL extends the WebAppManifest dictionary.
The share_target member of the manifest is a
ShareTarget dictionary that declares this application to be a
web share target, and describes how the application receives
share data.
A web share target is a web
site with a valid manifest containing a share_target member. A
web share target is a type of share target.
The steps for post-processing the share_target
member is given by the following algorithm. The algorithm takes
a ShareTargetshare target, a URLscope URL, and a URLmanifest URL. This algorithm
returns a ShareTarget or undefined.
If share target is undefined, then return
undefined.
If criterion is
type/subtype or
type/*, and the implementation
associates criterion with one or more file
extensions, append those file extensions to
bucket["accept"].
If criterion is a string whose first
character is a U+002E FULL STOP character (.), and the
implementation associates the file extension
criterion with a MIME type, append that MIME
type to bucket["accept"].
Let action be the result of parsing the URLshare
target["action"], relative
to the manifest URL and with no encoding override. If
the result is failure, issue a developer
warning and return undefined.
A use case for GET requests is when the share target
drafts a message for subsequent user approval. If the share target
performs a side-effect without any user interaction,
POST requests should be used.
Warning
The user agent MAY truncate the share data if method is
"GET" and an entry in the share data exceeds 2000 bytes.
The enctype member specifies how the share data is encoded
in the request.
The ShareTargetParams dictionary contains the following
members.
The title member specifies the name of the query parameter
used for the title of the document being shared.
The text member specifies the name of the query parameter
used for the arbitrary text that forms the body of the message being
shared.
The url member specifies the name of the query parameter
used for the URL string referring to a resource being shared.
The files member contains zero or more
ShareTargetFiles dictionaries.
3.4
ShareTargetFiles and its members
The ShareTargetFiles dictionary contains the following
members.
The name member specifies the name of the form field used
to share the files.
The accept member specifies a sequence of accepted MIME
type(s) or file extension(s), the latter expressed as strings
starting with U+002E FULL STOP (.).
4.
Registration of web share targets
How and when web share targets are "registered" is at the
discretion of the user agent and/or the end user. In fact,
"registration" is a user-agent-specific concept that is not formally
defined here; user agents are NOT REQUIRED to "register" web share
targets at all; they are only REQUIRED to provide some mechanism to
convey shared data to a web share target of the end user's choosing.
User agents MAY consider a web share target "registered" even if it is
not installed.
The user agent MAY automatically register all web share targets
as the user visits the site, but it is RECOMMENDED that more discretion
is applied, to avoid overwhelming the user with the choice of a large
number of targets.
Note
Examples of registration strategies that user agents can employ are:
Only register a web share target once it is installed.
Only register a web share target once the end user has used the
site for some period of time.
Only register a web share target if it has a service worker.
When presenting the end user with a list of web share targets,
the user agent MAY use an online service which has pre-indexed
manifests, and therefore show the user targets that they have never
visited or explicitly registered.
We may wish to provide a method for websites to explicitly request to prompt the user for handler registration. This would be limited to prompting to register the share_target already declared in the manifest (not dynamically creating share targets). For now, we have omitted such a method from the design to keep control in the hands of user agents. It is easier to add such a method later than remove it.
An implementation supports filtering on MIME types if it
takes into account the MIME types of the files being shared when
presenting the user with a choice of share targets.
An implementation supports filtering on file extensions if
it takes into account the extensions in the names of the files being
shared when presenting the user with a choice of share targets.
If a file being shared is not accepted by any of a share
target's files entries, the
user MUST NOT be presented with that web share target as an option.
5.
Handling incoming shares
A web share target is invoked when the end user is sharing some
data intended for a generic application, and indicates that specific
web share target as the receiver of the data.
It is not specified where the data comes from, or how the end user
indicates the web share target as the receiver. However, one possible
source is a call to navigator.share in the
same user agent.
Note
Examples of other possible sources of a web share target
invocation are:
From the built-in UI of the user agent (e.g., the end user
picks "Share" from a browser's menu, to share the current page title
as "title" and the current page URL as
"url").
A share action triggered from a native application (via a
proprietary share system), followed by the end user choosing a web
share target as the receiver.
5.1
Obtaining a ShareData
When a web share target is invoked, the data MAY be in
an unspecified format. The user agent MUST first convert the data
into a ShareData dictionary, if
it is not already, by mapping to the fields of ShareData
from equivalent concepts in the host system. If the source was a call
to navigator.share, the
user agent SHOULD use the ShareData argument
unmodified (but this is not always possible, as it might have to
round-trip through some other format in a lossy manner). The user
agent MAY employ heuristics to map the data onto the
ShareData fields as well as possible.
Note
For example, the host share system may not have a dedicated URL
field, but a convention that both plain text and URLs are sometimes
transmitted in a "text" field. This is the case on Android. The user
agent can check whether all or part of the "text" field is a
valid URL string, and if so,
move that part of the "text" field to the ShareData's url field.
If the first character of criterion is a U+002E
FULL STOP character (.) and shared
file["name"] ends with criterion,
and the implementation supports filtering on file
extensions, return true.
If criterion is
type/subtype (where
type and subtype are RFC7230 tokens) and matches the MIME
type of shared file, and the implementation supports
filtering on MIME types, return true.
If criterion is type/*
(where type is a RFC7230 token) and the MIME type of
shared file is a subtype of type, and the
implementation supports filtering on MIME types, return
true.
If criterion is */*, return
true.
Return false.
6.
Security and privacy considerations
This section is non-normative.
Invoking a web share target means potentially sending
private user data to a third-party website. Implementors are to take
every precaution that the user understands which party the data is
being sent to (e.g., communicating the web share target's
origin), before running the invocation algorithm.
Of particular concern is spoofing: a web share target presenting
itself as a different party (by setting its name and icon accordingly).
The spoofing risk is heightened if web share targets are chosen
from an online index, rather than a set of targets that the end user
has explicitly installed or registered.
The requirement that the web share target's origin be
potentially
trustworthy is to prevent private user data from being
transmitted to a party that does not control the origin in question,
or in clear text over the network.
A.
Acknowledgments
This section is non-normative.
Thanks to the Web Intents team, who laid
the groundwork for the web app interoperability use cases. In
particular, Paul Kinlan, who did
a lot of early advocacy for Web Share and Web Share Target.
Thanks to Connie Pyromallis, who wrote an early draft of this spec, and
helped design and prototype the API.
Thanks to Alex Russell and David Baron, for their feedback on early
drafts of this spec.