- PUT and DELETE with HTML Forms in ExpressJS
- General approach
- Using AJAX
- POST -ing with specific token
- Specific Token in Query String
- Specific Token in Form data
- Composition
- DELETE
- Syntax
- Example
- Request
- Responses
- File deleted.
- Specifications
- Browser compatibility
- See also
- Found a content problem with this page?
- MDN
- Support
- Our communities
- Developers
- Method override for PUT and DELETE in HTML
PUT and DELETE with HTML Forms in ExpressJS
In trying to send data from an HTML form to an ExpressJS backend I soon discovered two things:
- FORM elements only support GET and POST , not PUT , nor DELETE ;
- ExpressJS does not have a built-in way to address this but fortunately there’s a middleware plugin, method-override, that does.
method-override ’s documentation is great and very much on point, except for the FORM post override section, which I found a bit confusing on my first read (although in honesty, now it seems much clear).
As a result, and for my own clarification, I decided to put together as small example that showcases all the ways method-override can be used from within HTML pages.
General approach
Middleware in ExpressJS typically takes place early in the processing pipeline and as such method-override will attempt to identify a specific token in the received data, per configuration, and will, well, override the method aka HTTP verb used.
There are two main approaches we can use to trigger the app.put() and app.delete() route handlers from HTML code:
Using AJAX
Almost all current versions of browsers support specifying an HTTP method.
// client code var xhr = new XMLHttpRequest(); xhr.open('PUT', '/resource', true); xhr.send(); // --- // server code app.put('/resource', function(req, res) console.log('PUT to /resource'); >);
If you only work with modern browsers, there’s nothing more required.
However, if your front-end needs to be backward compatible with older versions that don’t support HTTP methods (enterprise software developers, I feel you), then method-override can be configured to look for a token in the headers being posted and override the method being used.
// server code var methodOverride = require('method-override'); app.use(methodOverride('X-HTTP-Method-Override')); app.put('/resource', .
As such, the client code needs to specify the intended method in a header:
// client code var xhr = new XMLHttpRequest(); xhr.open('POST', '/resource', true); // method-override needs it to be POST xhr.setRequestHeader('X-HTTP-Method-Override', 'PUT'); xhr.send();
POST -ing with specific token
If instead of AJAX, we intend to use the HTML’s FORM element to PUT or DELETE , method-override can be configured to look for a specific token either in the query string, or, with a tiny bit more code, in the data being submitted.
Specific Token in Query String
In this example we will have the form POST to /resource?_method=PUT and will configure method-override to look for _method in the query string and override the HTTP method with the indicated verb.
// server code app.use(methodOverride('_method')); app.put('/resource', .
On the client side, we’ll POST to the above URL:
// client code method="POST" action="/resource?_method=PUT"> .
Note: by default method-override only examines POST requests.
You can configure it to look at GET requests:
// server code app.use(methodOverride('_method', methods: ['POST', 'GET'] >);
but this is a really bad idea for two reasons:
- GET -ing /resource?_method=DELETE is downright dangerous as anything unintentionally (or worse, intentionally) crawling your URLs will cause deletion of resources; this could be something as trivial as a browser pre-fetching links in order to speed up pages, or a browser extension investigating URLs for any number of reasons (phishing protection, status checking, statistics, etc).
- GET -ing /resource?_method=PUT with a payload makes no sense from an HTTP standard perspective. Payloads are for POST and PUT .
Specific Token in Form data
The second method involved sending the token with the POST body. The most common approach is to include a hidden field.
method="POST" action="/log" enctype="application/x-www-form-urlencoded"> type="hidden" name="_method" value="PUT"> type="submit">Submit
The server-side code is a little bit more involved this time as it requires another library: body-parser , which you’re likely to use anyway if you deal with form data or just HTTP body data in general.
body-parser inteprets the incoming HTTP request body and makes it available as key-value pairs in the body property of the request, req , parameter.
method-override allows one to specify a custom function to be called during the middleware execution. In this custom function we will inspect the request body, req.body , for the presence of the desired token, _method in this case, and return its value to the middleware that will in turn override the request method.
// server code var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded( extended: false >)); app.use(methodOverride(function (req, res) if (req.body && typeof req.body === 'object' && '_method' in req.body) // look in urlencoded POST bodies and delete it var method = req.body._method; delete req.body._method; return method; > >));
Composition
As a final note, it’s worth mentioning that you can have multiple method-override s in your middleware code, thus allowing the handling of all the scenarios presented above.
Except for the GET + DELETE scenario. You should never do that.
// server code var express = require('express'); var bodyParser = require('body-parser'); var methodOverride = require('method-override'); var app = express(); app.use(methodOverride('X-HTTP-Method-Override')); app.use(methodOverride('_method')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded( extended: false >)); app.use(methodOverride(function (req, res) if (req.body && typeof req.body === 'object' && '_method' in req.body) var method = req.body._method; delete req.body._method; return method; > >)); app.get('/resource', . ) .get('/resource/:id', . ) .post('/resource', . ) .put('/resource/:id', . ) .delete('/resource/:id', . );
If you want to see all the examples above in action, clone my method-override-example repo and simply run npm start then navigate to http://localhost:3000/ to play with each of these scenarios.
So? Liked it? Hated it? Thought it was stupid? Thought I was stupid? Deemed it to be informative? Want to lavish excessive praise or cast fiery insults? Contact me and have at it.
All original content is licensed under a Creative Commons Attribution 3.0 Unported License. Content quoted from elsewhere, including source code, is covered by the original sources’ respective licenses.
DELETE
The HTTP DELETE request method deletes the specified resource.
Request has body | May |
---|---|
Successful response has body | May |
Safe | No |
Idempotent | Yes |
Cacheable | No |
Allowed in HTML forms | No |
Syntax
Example
Request
DELETE /file.html HTTP/1.1 Host: example.com
Responses
If a DELETE method is successfully applied, there are several response status codes possible:
- A 202 ( Accepted ) status code if the action will likely succeed but has not yet been enacted.
- A 204 ( No Content ) status code if the action has been enacted and no further information is to be supplied.
- A 200 ( OK ) status code if the action has been enacted and the response message includes a representation describing the status.
HTTP/1.1 200 OK Date: Wed, 21 Oct 2015 07:28:00 GMTFile deleted.
Specifications
Browser compatibility
BCD tables only load in the browser
See also
Found a content problem with this page?
This page was last modified on Apr 10, 2023 by MDN contributors.
Your blueprint for a better internet.
MDN
Support
Our communities
Developers
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.
Method override for PUT and DELETE in HTML
Following four HTTP methods are commonly used in REST.
• GET — This is to provide a read-only access to resource.
• PUT — This is to create a new resource
• DELETE — This is to remove a resource
• POST — This is to update a existing resource or create a new resource.
When we try to use PUT and DELETE in HTML, we have a problem. Browsers do support PUT and DELETE but it only by using request via AJAX, but not via ‘HTML form’ submission.
In both HTML4 and HTML5 spec, it says that the only HTTP methods that HTML form element should allow are «GET» and «POST». There is no clear reason why PUT and DELETE are not supported by ‘HTML form’. My understanding is POST can be more effectively reused to support PUT and DELETE method. PUT and DELETE typically don’t redirect to an appropriate page, while POST will redirect accordingly. We probably don’t need to reinvent PUT and DELETE method for HTML but just reuse POST in this case (this is my opinion).
As the purpose of this page to understand how to use «method override» middleware to get around this problem.
The following is probably the most popular way to get it done.
First, install npm package for method-override.
$ npm install method-override
The idea is to use a header to override the method. The following example is to override POST method to create PUT and DELETE method.
Specify the header name a string argument of «methodOverride»
const methodOverride = require(‘method-override’);
Override with ‘_method’ header in the request. You can choose your own header.
app.use(methodOverride(‘_method’));
‘post’ is allowed method by HTTP form. We can override this post method for the following «put» and «delete» method.
app.post(‘/ideas’, (req, res) => //
>);
«put» method is overriden post method.
app.put(‘/ideas/:id’, (req, res) => //
>);
«delete» method is overriden post method.
app.delete(‘/ideas/:id’, (req, res) => //
>);