This is an addendum to the specification of HTML5 forms extending the abilities of configuring HTTP requests through HTML markup.
This document has been developed as a result of work contributed in addressing HTML WG ISSUE-195: Enhance http request generation from forms.
This specification is an extension specification to HTML.
The use of forms in HTML provide a declarative interface for capturing user input for interaction with remote web services over the HTTP protocol.
This specification builds upon the standardization of XMLHttpRequest [[XHR]] by extending the functionality available to configure HTTP requests in JavaScript interfaces to declarative form attributes and controls.
The set of changes herein remove the restriction on HTTP methods allowing both the use of the common HTTP methods PUT and DELETE, while also allowing HTTP extension-methods for unstandardized private or experimental use.
A new payload
submission attribute is introduced to enable
the configuration of the HTTP message generated in form submit. This allows
flexibility in the configuration of URL query parameters, HTTP headers and
message data through input controls.
The use of named form control fields is extended to include HTTP
Authentication parameters synonymous with the XMLHttpRequest
open
method arguments which are managed by the User Agent. This
introduces declarative "login" and "logout" forms defined by protocol and
provides an alternative to the use of stateful cookies for HTTP session
continuation.
The sub-sections of this document correlate to the revised sections of the HTML5 [[!HTML5]] specification and identify the complete set of changes with the exception of nominal referential updates.
method
Attribute4.10.19 Attributes common to form controls
The method
and
formmethod
content attributes, if specified, must be a valid HTTP
method or extension-method [[!HTTP11]] with the exception of the
following keywords and states which are forbidden:
connect
,
mapping to the state CONNECT,
indicating the HTTP CONNECT method.trace
,
mapping to the state TRACE,
indicating the HTTP TRACE method.track
,
mapping to the state TRACK,
indicating the HTTP TRACK method.The invalid value default for these attributes is the GET state. (There is no missing value default.)
The method of an element is
the corresponding state. If the element is a submit button and has a formmethod
attribute, then the
element's method is that
attribute's state; otherwise, it is the form owner's
method
attribute's state.
payload
Attributepayload
interface <HTMLSubmittableElement> {
attribute DOMString payload;
};
4.10.19 Attributes common to form controls
<ADDENDUM> Binding form controls: the payload
attribute
The payload
attribute
on a form control is used to specify the binding of the control to a
scheme data set for form submission. The attribute is an enumerated
attribute with the following keywords and states:
_action
,
mapping to the state ACTION,
indicating that the value is a member of the form action set._header
,
mapping to the state HEADER,
indicating that the value is a member of the form header set._body
,
mapping to the state BODY,
indicating that the value is a member of the form body set.If the element does not have such an attribute then the value is
determined within the context of the form
, or the
submitter during form submission:
If the scheme is http(s)
and the method is
HEAD, GET, OPTIONS or DELETE then the payload
is the
ACTION state.
If the scheme is http(s)
and the method is
PUT, POST, PATCH or an extension-method then the payload
is the BODY state.
For the data
and mailto
schemes the
missing value default is the
BODY state.
4.10.19 Attributes common to form controls
4.10.19.1 Naming form controls: the name
attribute
The name
content
attribute gives the name of the form control, as used in form
submission and in the form
element's elements
object. If the attribute
is specified, its value must not be the empty string.
Any non-empty value for name
is allowed, but the names
"isindex
",
"_charset_
",
"_username_
",
"_password_
" and
"_logout_
" are special:
isindex
This value, if used as the name of a Text control that is the first
control in a form that is submitted using the application/x-www-form-urlencoded
mechanism, causes the submission to only include the value of this
control, with no name.
_charset_
This value, if used as the name of a Hidden control with no value
attribute, is automatically
given a value during submission consisting of the submission
character encoding.
_username_
This value, if used as the name of a Text or Email control, is used as a
named parameter for a HTTP Authentication scheme
[[!RFC2617]] if supported by the user agent and the form does not
contain an Authorization
request header.
_password_
This value, if used as the name of a Password control, is used as
a named parameter for a HTTP Authentication scheme
[[!RFC2617]] if supported by the user agent and the form does not
contain an Authorization
request header.
_logout_
This value, if used as the name of a Hidden control, causes a User Agent which supports HTTP Authentication and reuses authenticated credentials across requests to clear any credentials for the protection space on receiving a HTTP success code (2XX) response [[!RFC2617]].
The name
IDL
attribute must reflect the name
content attribute.
4.10.22.3 Form submission algorithm
When a form
element form is submitted from an element submitter (typically a button), optionally with a
submitted from submit()
method flag set, the
user agent must run the following steps:
Let form document be the form's Document
.
If form document has no associated browsing context or its active sandboxing flag set has its sandboxed forms browsing context flag set, then abort these steps without doing anything.
Let form browsing context be the browsing context of form document.
If the submitted from submit()
method flag is not
set, and the submitter element's no-validate state is false,
then interactively validate the constraints of form and examine the result: if the result is
negative (the constraint validation concluded that there were
invalid fields and probably informed the user of this) then abort
these steps.
If the submitted from submit()
method flag is not
set, then fire a simple event that is cancelable named
submit
, at form. If the event's default action is prevented
(i.e. if the event is canceled) then abort these steps. Otherwise,
continue (effectively the default action is to perform the
submission).
Let action be the result of constructing the form action for form in the context of submitter.
If action is the empty string, let action be the document's address of the form document.
This step is a willful violation of RFC 3986, which would require base URL processing here. This violation is motivated by a desire for compatibility with legacy content. [[!RFC3986]]
Resolve the URL action, relative to the submitter element. If this fails, abort these steps. Otherwise, let action be the resulting absolute URL.
Let scheme be the <scheme> of the resulting absolute URL.
Let method be the submitter element's method.
Let form action set be the result of constructing a form payload set for form in the context of submitter with payload type ACTION.
Let form header set be the result of constructing a form payload set for form in the context of submitter with payload type HEADER.
Let form body set be the result of constructing a form payload set for form in the context of submitter with payload type BODY.
Let enctype be the submitter element's enctype.
Let target be the submitter element's target.
If the user indicated a specific browsing context to use when submitting the form, then let target browsing context be that browsing context. Otherwise, apply the rules for choosing a browsing context given a browsing context name using target as the name and form browsing context as the context in which the algorithm is executed, and let target browsing context be the resulting browsing context.
If target browsing context was created in the previous step, or if the form document has not yet completely loaded, then let replace be true. Otherwise, let it be false.
Otherwise, select the appropriate behavior based on the value of scheme and jump to the steps therein.
If scheme is not one of those listed in below, then the behavior is not defined by this specification. User agents should, in the absence of another specification defining this, act in a manner analogous to that defined in this specification for similar schemes.
The behaviors are as follows:
http(s)
If method is anything but GET or POST, and the origin of action is not the same origin as that of form document, then user agents may abort these steps, or perform a cross-origin pre-flight verification [[CORS]].
Let query be the result of encoding the
form action set using the application/x-www-form-urlencoded
encoding
algorithm, interpreted as a US-ASCII string.
Let destination be a new URL that is equal to the action except that its <query> component is replaced by query (adding a U+003F QUESTION MARK character (?) if appropriate).
Let request headers be a list of HTTP header names and and corresponding header values, initially empty.
Loop: For each entry in form header set, run the following substeps:
If the name of the entry does not match the field-name production [[!HTTP11]], then skip these substeps.
If the value of the entry does not match the field-value production [[!HTTP11]], then skip these substeps.
If the name of the entry is a case-insensitive match for any of the following set of forbidden headers, then the skip these substeps:
...or if the start of name is a
case-insensitive match for Proxy-
or
Sec-
(including when header is just Proxy-
or Sec-
).
If the list of request headers does not contain a case-insensitive match of the name of the entry, then append the name and value to the list of request headers.
Otherwise, combine the value of the matched request header with the value of the entry using a single U+002C COMMA character (,) as separator [[!HTTP11]].
Let request username be the value of the
first control in the form with name
"_username_
" and with type "text
" or
"email
", or null if no such element exists.
Let request password be the value of the
first control in the form with name
"_password_
" and with type "password
",
or null if no such element exists.
If the list of request headers does not
contain an Authorization
header and the resource was
returned with an WWW-Authenticate
response header,
the user agent should answer the strongest authentication
challenge using the request username and
request password as authentication scheme
parameters and add the header to the list of
request headers.
Let entity body be the result of encoding the form body set using the appropriate form encoding algorithm.
Let MIME type be determined as follows:
application/x-www-form-urlencoded
application/x-www-form-urlencoded
".multipart/form-data
multipart/form-data;
", a
U+0020 SPACE character, the string "boundary=
", and the multipart/form-data
boundary string
generated by the multipart/form-data
encoding
algorithm.text/plain
text/plain
".Navigate target browsing context to action using the HTTP method given by method applying any additional request headers and with entity body as the entity body, of type MIME type. If replace is true, then target browsing context must be navigated with replacement enabled.
If the user agent supports HTTP Authentication and
Authorization
is not in the list of
request headers, it should respond to a 401 Unauthorized
authentication challenge using the request username
and request password as authentication
scheme parameters.
If the request username is null and request password is null the user agent should prompt the end user for authentication challenge parameters.
data
Let data be the result of encoding the form body set using the appropriate form encoding algorithm.
If action contains the string "%%%%
" (four U+0025 PERCENT SIGN characters),
then %-escape all bytes in data that, if
interpreted as US-ASCII, do not match the unreserved
production in the URI Generic Syntax,
and then, treating the result as a US-ASCII string, further
%-escape all the U+0025 PERCENT SIGN characters in the resulting
string and replace the first occurrence of "%%%%
" in action with the
resulting double-escaped string. [[!RFC3986]]
Otherwise, if action contains the string
"%%
" (two U+0025 PERCENT SIGN characters
in a row, but not four), then %-escape all characters in data that, if interpreted as US-ASCII, do not
match the unreserved
production in the URI
Generic Syntax, and then, treating the result as a US-ASCII
string, replace the first occurrence of "%%
" in action with the
resulting escaped string. [[!RFC3986]]
Navigate target
browsing context to the potentially modified action (which will be a data:
URL). If replace is true, then target
browsing context must be navigated with replacement
enabled.
mailto
Let destination have the same value as action.
Let recipients be the resulting encoding the form action set by concatenating the elements using a U+002C COMMA character (,) deliminator.
Replace occurrences of U+002B PLUS SIGN characters (+) in
recipients with the string "%20
".
If recipients is not the empty string, let destination consist of all the characters from the first character in destination to the character immediately before the first U+003F QUESTION MARK character (?), if any, or the end of the string if there are none.
Append recipients to destination.
Let headers be the resulting encoding the
form header set using the application/x-www-form-urlencoded
encoding
algorithm, interpreted as a US-ASCII string.
Replace occurrences of U+002B PLUS SIGN characters (+) in
headers with the string "%20
".
If destination does not contain a U+003F QUESTION MARK character (?), append a single U+003F QUESTION MARK character (?) to destination. Otherwise, append a single U+0026 AMPERSAND character (&).
Append headers to destination.
Let body be the resulting encoding the
form body set using the appropriate
form encoding algorithm and then %-escaping all the bytes
in the resulting byte string that, when interpreted as US-ASCII,
do not match the unreserved
production in
the URI Generic Syntax. [[!RFC3986]]
If destination does not contain a U+003F QUESTION MARK character (?), append a single U+003F QUESTION MARK character (?) to destination. Otherwise, append a single U+0026 AMPERSAND character (&).
Append the string "body=
" to destination.
Append body, interpreted as a US-ASCII string, to destination.
Navigate target browsing context to destination. If replace is true, then target browsing context must be navigated with replacement enabled.
The appropriate form encoding algorithm is determined as follows:
application/x-www-form-urlencoded
application/x-www-form-urlencoded
encoding
algorithm.multipart/form-data
multipart/form-data
encoding
algorithm.text/plain
text/plain
encoding
algorithm.4.10.22.4 Constructing a form payload set
The algorithm to construct a form payload set for a form form optionally in the context of a submitter submitter is as follows. If not specified otherwise, submitter is null.
Let payload be the payload type whose data set is to be constructed.
Let controls be a list of all the submittable elements whose form owner is form, in tree order.
Let the form payload set be a list of name-value-type tuples, initially empty.
Loop: For each element field in controls, in tree order, run the following substeps:
If any of the following conditions are met, then skip these substeps for this element:
payload
attribute state which is not equal to
payload.datalist
element ancestor.input
element whose name
attribute value is
"_username_
" or
"_password_
".input
element whose type
attribute is in the Checkbox state and
whose checkedness is
false.input
element whose type
attribute is in the Radio Button state and
whose checkedness is
false.input
element whose type
attribute is in the Image Button state, and
either the field element does not have a
name
attribute specified, or
its name
attribute's value is
the empty string.object
element that is not using a
plugin.Otherwise, process field as follows:
Let type be the value of the type
IDL attribute of field.
If the field element is an
input
element whose type
attribute is in the Image Button state,
then run these further nested substeps:
If the field element has a name
attribute specified and its
value is not the empty string, let name be
that value followed by a single U+002E FULL STOP character (.).
Otherwise, let name be the empty
string.
Let namex be the string consisting of the concatenation of name and a single U+0078 LATIN SMALL LETTER X character (x).
Let namey be the string consisting of the concatenation of name and a single U+0079 LATIN SMALL LETTER Y character (y).
The field element is submitter, and before this algorithm was invoked the user indicated a coordinate. Let x be the x-component of the coordinate selected by the user, and let y be the y-component of the coordinate selected by the user.
Append an entry to the form payload set with the name namex, the value x, and the type type.
Append an entry to the form payload set with the name namey and the value y, and the type type.
Skip the remaining substeps for this element: if there are any more elements in controls, return to the top of the loop step, otherwise, jump to the end step below.
Let name be the value of the field element's name
attribute.
If the field element is a
select
element, then for each option
element in the select
element whose selectedness is true,
append an entry to the form payload set with the
name as the name, the value of the
option
element as the value, and type as the type.
Otherwise, if the field element is an
input
element whose type
attribute is in the Checkbox state or the
Radio Button state,
then run these further nested substeps:
If the field element has a value
attribute specified, then
let value be the value of that attribute;
otherwise, let value be the string
"on
".
Append an entry to the form payload set with name as the name, value as the value, and type as the type.
Otherwise, if the field element is an
input
element whose type
attribute is in the File Upload state, then for
each file selected in the
input
element, append an entry to the form payload set with the name as
the name, the file (consisting of the name, the type, and the
body) as the value, and type as the type. If
there are no selected files,
then append an entry to the form payload set
with the name as the name, the empty string
as the value, and application/octet-stream
as the
type.
Otherwise, if the field element is an
object
element: try to obtain a form submission
value from the plugin,
and if that is successful, append an entry to the form payload set with name as the
name, the returned form submission value as the value, and the
string "object
" as the type.
Otherwise, append an entry to the form payload set with name as the name, the value of the field element as the value, and type as the type.
If the element has a dirname
attribute, and that
attribute's value is not the empty string, then run these
substeps:
Let dirname be the value of the
element's dirname
attribute.
Let dir be the string "ltr
" if the directionality of the
element is 'ltr', and "rtl
" otherwise (i.e. when the
directionality of the element is 'rtl').
Append an entry to the form payload set
with dirname as the name, dir as the value, and the string "direction
" as the type.
An element can only have a dirname
attribute if it is a
textarea
element or an input
element
whose type
attribute is in
either the Text state
or the Search
state.
End: For the name of each entry in the form payload set, and for the value of each entry in
the form payload set whose type is not "file
" or "textarea
", replace
every occurrence of a U+000D CARRIAGE RETURN (CR) character not
followed by a U+000A LINE FEED (LF) character, and every
occurrence of a U+000A LINE FEED (LF) character not preceded by a
U+000D CARRIAGE RETURN (CR) character, by a two-character string
consisting of a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF)
character pair.
In the case of the value of textarea
elements, this newline normalization is already performed during
the conversion of the control's raw value into the
control's value (which also
performs any necessary line wrapping). In the case of
input
elements type
attributes in the File Upload state, the value
is not normalized.
Return the form payload set.
This form is used to updated an existing resource with the new content within the entity, but only if the entity has not been modified since the current version:
<form action="http://www.example.com/cms/hogmanay" method="PUT"> <input name="If-Unmodified-Since" type="hidden" value="Tue, 1 Jan 2013 12:00:00 GMT" payload="_header"/> <textarea name="content"> For auld lang syne, my dear, For auld lang syne. We'll tak a cup o' kindness yet, For auld lang syne. And there's a hand, my trusty fere! And gie's a hand o' thine! And we'll tak a right gude-willie waught, For auld lang syne. </textarea> <button type="submit">Update</button> </form>
This form is used to delete a range of resources:
<form action="http://www.example.com/logs" method="DELETE"> <label for="since">Since</label> <input id="since" name="since" type="datetime"/> <button type="submit">Delete</button> </form>
This HTTP response includes a form which provides the parameters for HTTP authentication from input controls:
HTTP/1.1 200 OK Content-Type: text/html WWW-Authenticate: BASIC realm=MyRealm <html> <body> <form action="http://www.example.com/login" method="POST"> <label for="user">Username</label> <input id="user" name="_username_" type="text"/> <label for="pass">Password</label> <input id="pass" name="_password_" type="password"/> <button type="submit">Login</button> </form> </body> </html>
This form sends a logout request to the server which may clear any session cookies, and instructs the user agent to clear the authentication cache:
<form action="http://www.example.com/logout" method="POST"> <input name="_logout_" type="hidden"/> <button type="submit">Logout</button> </form>
This form captures the inputs for sending an email through a mailto URI:
<form action="mailto:"> <label for="to">To</label> <input id="to" name="to" type="email" payload="_action"/> <label for="cc">Cc</label> <input id="cc" name="cc" type="email" payload="_header"/> <label for="bcc">Bcc</label> <input id="bcc" name="bcc" type="email" payload="_header"/> <label for="subject">Subject</label> <input id="subject" name="subject" type="text" payload="_header"/> <label>Content</label> <textarea size="50"/> <button type="submit">Send</button> </form>
Acknowledgements and thanks go to the following people for their efforts which have contributed to this specification:
And of course, many thanks to Robin Berjon for making our lives so much easier with his cool specification authoring tool.