Hello WHATWG! I'm reading the section for enctype and found that there's no state for application/json or something similar that allows form submission in JSON.
I ignore the reasons that forced W3C to stop maintaining that specification. But I'm wondering if that spec worths or not?
Thanks for your time.
It's a lot of added complexity for little value. And there is no implementer interest because of that.
If I want to convert a form into an object, I may implement a simple solution... something like
// convert the form into an object
var formObj = {};
for (var i = 0; i < form.length; i++) {
if (form[i].id) {
formObj[form[i].id] = form[i].value;
}
}
@annevk, thanks for the information.
You can also use FormData(form). Perhaps we should expose a toJSON on FormData. That might be fairly reasonable.
Hmm... sounds good.
Here's my current version, without toJSON()
form.addEventListener('submit', e => {
e.preventDefault();
var formObj = {};
var fd = new FormData(e.target);
for (var item of fd) {
formObj[item[0]] = item[1];
}
fetch(`/api/category/${formObj.id}`, {
method: 'put',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: JSON.stringify(formObj)
});
});
Let me dream a bit, please...
With toJSON()
form.addEventListener('submit', e => {
e.preventDefault();
var fd = new FormData(e.target).toJSON();
fetch(`/api/category/${formObj.id}`, {
method: 'put',
body: fd // then the fetch process should guess the content-type
});
});
Or just by setting the content-type
form.addEventListener('submit', e => {
e.preventDefault();
var fd = new FormData(e.target);
fetch(`/api/category/${formObj.id}`, {
method: 'put',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: fd // the fetch process will call toJSON automatically
});
});
The main goal that I see here is the possibility to expose the form depending on the content-type.
@annevk do you want to move this to XHR to add a toJSON() and close this issue?
I opened https://github.com/whatwg/xhr/issues/84 though given your comments in https://github.com/whatwg/url/issues/143 I wonder whether returning a JSON object here is the way to go.
@rianby64 if you're satisfied with this resolution please close this issue. Your last idea goes a tad too far I think. We don't really want browsers to inspect the headers to determine how to serialize a value. That's too much action-at-a-distance.
So, the first variant seems to be better than the second one. Nice :smile: ! Thanks a million!
Coming a bit late (6 month) to this topic (just saw it), but would like to share my view on application/json as "enctype" attribute value
JSON, form URL encoded, and plain text
JSON encoding is more or less like the "x-www-form-urlencoded" format. It is not designed to embed binary data. As such, both the application/x-www-form-urlencoded serializer and the text/plain encoding algorythm says that they serialize "file" entries in form data by replacing their value with their file's name only. Base64 encoding has been estimated as a no go for files use case (to much overhead).
So I think it would be fair to says that either native XHR/fetch support or form data toJSON() method should behave the same.
What for?
Well
Multipart, form-data, and JSON
The way we send files over XMLHttpRequest / Fetch is either sending directly a File/Blob/ArrayBuffer as the main body or via a FormData, with files entries, using the "multipart/form-data" encoding.
"multipart" is the MIME type standard to mix binary, plain text, and any formatted data in "parts" joined in a single body.
So if we would like to send Form entries including files using JSON encoding, the only approach I would imagine is defining a "multipart/json-form-data" or more easily "multipart/form-data+json" (standard way to indicate a JSON flavor of an existing format. It would look very much like classic "form-data" but may benefit from few JSON formating advantages.
In multipart/form-data MIME format, each Form entry becomes a MIME part with its own Headers.
The main "part header" is Content-Disposition. (ex: Content-Disposition: form-data; name="field1"). It provides the form entry name. If the entry is a file, it cans contain also the file name (ex: Content-Disposition: form-data; name="myFile"; filename="summary.pdf")
The second main "part header" is Content-Type, which default value is "text/plain" if not provided (as for standard input entries), but this value is important for files. It can have a specific MIME type, if detected, based on the embedded file (ex: application/pdf). By default it will be "application/octet-stream".
In a JSON flavor, "non-file" parts could have their "Content-type" set to "application/json"
What for?
<select>, "radio" type, or other <input> entries with the multiple attribute) could be grouped in a single part using the array JSON notation (for non-binary ones)That's all... Just wanted to share what kind of bell this feature request did ring to me.
Still, I agree, server side frameworks usually work pretty well with classic form data... But well, getting automatically the right value type would be an extra I often felt was missing.
PS: of course another thing is to consider if such "enctype" is acceptable with both GET/POST methods, or only for POST ones (like multipart/form-data), potentially because some HTTP client/proxy/server may not support JSON in URLs if not URL encoded...
I also think it would be useful to make enctype="application/json" work
<form method="post" action="https://httpbin/post" enctype="application/json">
<input name="foo" value="bar">
<input type="submit">
</form>
https://jsfiddle.net/crl/cj9f0qna/ foo=bar is sent when submitting, instead of {"foo":"bar"} if enctype="application/json" were implemented
The problem is that any on-the-wire extension to forms requires navigation to become CORS-aware, which would be rather involved and with lots of details to think through. Coupled with lack of active implementer interest it doesn't really seem like something that's going to happen anytime soon.
Perhaps once navigation is refactored better so that it's more clear what the consequences would be.
Most helpful comment
Coming a bit late (6 month) to this topic (just saw it), but would like to share my view on
application/jsonas"enctype"attribute valueJSON, form URL encoded, and plain text
JSON encoding is more or less like the "x-www-form-urlencoded" format. It is not designed to embed binary data. As such, both the application/x-www-form-urlencoded serializer and the text/plain encoding algorythm says that they serialize "file" entries in form data by replacing their value with their file's name only. Base64 encoding has been estimated as a no go for files use case (to much overhead).
So I think it would be fair to says that either native XHR/fetch support or form data toJSON() method should behave the same.
What for?
Well
Multipart, form-data, and JSON
The way we send files over
XMLHttpRequest/Fetchis either sending directly aFile/Blob/ArrayBufferas the main body or via aFormData, with files entries, using the"multipart/form-data"encoding."multipart" is the MIME type standard to mix binary, plain text, and any formatted data in "parts" joined in a single body.
So if we would like to send Form entries including files using JSON encoding, the only approach I would imagine is defining a
"multipart/json-form-data"or more easily"multipart/form-data+json"(standard way to indicate a JSON flavor of an existing format. It would look very much like classic "form-data" but may benefit from few JSON formating advantages.In
multipart/form-dataMIME format, each Form entry becomes a MIME part with its own Headers.The main "part header" is
Content-Disposition. (ex:Content-Disposition: form-data; name="field1"). It provides the form entry name. If the entry is a file, it cans contain also the file name (ex:Content-Disposition: form-data; name="myFile"; filename="summary.pdf")The second main "part header" is
Content-Type, which default value is "text/plain" if not provided (as for standard input entries), but this value is important for files. It can have a specific MIME type, if detected, based on the embedded file (ex: application/pdf). By default it will be "application/octet-stream".In a JSON flavor, "non-file" parts could have their "
Content-type" set to "application/json"What for?
<select>,"radio"type, or other<input>entries with themultipleattribute) could be grouped in a single part using the array JSON notation (for non-binary ones)That's all... Just wanted to share what kind of bell this feature request did ring to me.
Still, I agree, server side frameworks usually work pretty well with classic form data... But well, getting automatically the right value type would be an extra I often felt was missing.