This adds put, patch, and delete values to the form element's method attribute, resolving #3577. It relies on a corresponding change to fetch spec, which allows mode=navigate fetches to make CORS preflight requests (fetch spec PR #1785).
Per the checklist, I'm refraining from pinging until implementer support is lined up and tests are written. Nevertheless I am opening this PR so that the approach can be read and validated by interested parties.
Summary of Modifications
Modifications to navigation are difficult—"Welcome to the dragon's maw," HTML 7.4 warns—but every effort has been made to ensure that this change is as precise as possible, while taking care to update terminology to match the enhanced functionality.
- Form element
- Add PUT, PATCH, and DELETE as values for the method attribute
- Demonstrate PUT and DELETE support with examples
- Specify PUT, PATCH, and DELETE behavior for non-HTTP schemes
- Initiate navigation with appropriate method
- Navigation
- Add "method" to Session History Entry struct (defaults to GET)
- Update navigation to set fetch method based on Session History Entry method
- Rename "POST Resource" to "Request Resource", and rename derivative variables
- Rename "allowPost" to "allowUnsafe"
- Add the ability—though not a requirement—for session restoration to re-perform idempotent requests
In addition to enabling additional form methods, the navigation work in particular removes the assumption in the specification that the presence of a request body (technically, a POST Resource) implies a POST request, paving the way for the addition of increased HTTP capabilities in HTML.
Details and Correctness
Here I outline exactly which lines in the specification fulfill the goals first outlined in "Support PUT, PATCH, and DELETE in HTML Forms" (Triptych Proposal #1), proposed in this comment on #3577, and favorably reviewed by WHATNOT on 2024-08-22. I certainly expect that spec experts will request modifications to this proposal—this section serves to highlight my own assumptions, in order to make the process of fixing any errors as easy as possible.
Rendering + Redirection
In short, the new methods should behave identically to the old methods with respect to response content and redirection. Response content should be rendered in the document, after following redirects. This is handled in HTML 7.4.5, which does not currently switch on method.
The only change made to this section is to set the fetch method based on the new Session History Entry method, rather than the presence of a request resource (f.k.a POST resource).
Form Data Behavior
HTML 4.10.21.3 describes what the browser should do with form data, based on the form's method attribute.
http | Mutate action URL | Submit as entity body |
https | Mutate action URL | Submit as entity body |
ftp | Get action URL | Get action URL |
javascript | Get action URL | Get action URL |
data | Mutate action URL | Get action URL |
mailto | Mail with headers | Mail as body |
In addition to adding PUT, PATCH, and DELETE as permitted values for that attribute, this table is extended such that DELETE matches GET behavior (i.e. including form data in the URL as a query parameter), and PUT and PATCH match POST behavior.
Additionally, the form element now passes its method to the navigate algorithm.
CORS
A fetch returns a network error if a request is made that does not comply with existing CORS requirements (i.e. the preflight fetch fails). HTML 7.4.5 will abort the navigation if this happens. This means that not only will navigation work with CORS-restricted methods, they are automatically safer for developers to use.
The only change required here is the linked fetch spec PR #1785 , which allows mode=navigation fetches to make CORS preflight requests.
Refresh and reloading behavior
HTML 7.8 directs the user agent to prompt the user before reloading navigables whose active session history entry's document state's resource is a request resource (f.k.a. POST resource). This generalizes that statement to direct the user agent to prompt the user before reloading navigables whose active session history entry's method (newly added field) is not idempotent.
User agents can, of course, choose to prompt on idempotent-but-unsafe methods like PUT as well, but this change permits them to resubmit the request automatically, as allowed by the HTTP RFC.
Additional Notes
custommethod Attribute
Section 9.1 of the proposal includes a custommethod attribute for forms, which overwrites the method attribute. I believe this additional attribute is very important for adoption, as the existing method's fallback to GET on unknown values poses an unacceptable risk in many contexts.
Nevertheless, custommethod is omitted from this proposal for simplicity's sake. It can be somewhat trivially added later if this succeeds.
Non-fetch link schemes
The non-fetch link schemes for PUT, PATCH, and DELETE were chosen to follow the principle of lease surprise. With respect to fetch schemes, PUT and PATCH mirror the behavior of POST, while DELETE mirrors that of GET; non-fetch schemes do the same.
Nevertheless, it clearly doesn't make a ton of sense to send a DELETE request to a mailto link. While I think there is likely no harm in allowing this—it's legal HTTP, the browser is already capable of doing it—I also don't think it's important, and would be fine having this be a no-op.
- At least two implementers are interested (and none opposed):
- …
- …
- Tests are written and can be reviewed and commented upon at:
- …
- Implementation bugs are filed:
- Chromium: …
- Gecko: …
- WebKit: …
- Deno (only for timers, structured clone, base64 utils, channel messaging, module resolution, web workers, and web storage): …
- Node.js (only for timers, structured clone, base64 utils, channel messaging, and module resolution): …
- Corresponding HTML AAM & ARIA in HTML issues & PRs:
- MDN issue is filed: …
- The top of this comment includes a clear commit message to use.
(See WHATWG Working Mode: Changes for more details.)
/acknowledgements.html ( diff )
/browsing-the-web.html ( diff )
/document-lifecycle.html ( diff )
/document-sequences.html ( diff )
/form-control-infrastructure.html ( diff )
/infrastructure.html ( diff )
/nav-history-apis.html ( diff )