Ð ÑÑой главе ÑеÑÑ Ð¿Ð¾Ð¹Ð´ÑÑ Ð¾Ð± оÑпÑавке HTML-ÑоÑм: Ñ Ñайлами и без, Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑми полÑми и Ñак далее. ÐбÑекÑÑ FormData помогÑÑ Ð½Ð°Ð¼ Ñ ÑÑим. Ðак вÑ, навеÑнÑка, догадалиÑÑ Ð¿Ð¾ его названиÑ, ÑÑо обÑекÑ, пÑедÑÑавлÑÑÑий даннÑе HTML ÑоÑмÑ.
ÐонÑÑÑÑкÑоÑ:
let formData = new FormData([form]);
ÐÑли пеÑедаÑÑ Ð² конÑÑÑÑкÑÐ¾Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ HTML-ÑоÑÐ¼Ñ form, Ñо ÑоздаваемÑй обÑÐµÐºÑ Ð°Ð²ÑомаÑиÑеÑки пÑоÑиÑÐ°ÐµÑ Ð¸Ð· Ð½ÐµÑ Ð¿Ð¾Ð»Ñ.
Ðго оÑобенноÑÑÑ Ð·Ð°ÐºÐ»ÑÑаеÑÑÑ Ð² Ñом, ÑÑо меÑÐ¾Ð´Ñ Ð´Ð»Ñ ÑабоÑÑ Ñ ÑеÑÑÑ, напÑÐ¸Ð¼ÐµÑ fetch, позволÑÑÑ ÑказаÑÑ Ð¾Ð±ÑÐµÐºÑ FormData в ÑвойÑÑве Ñела запÑоÑа body.
Ðн бÑÐ´ÐµÑ ÑооÑвеÑÑÑвÑÑÑим обÑазом закодиÑован и оÑпÑавлен Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð¼ Content-Type: multipart/form-data.
То еÑÑÑ, Ð´Ð»Ñ ÑеÑвеÑа ÑÑо вÑглÑÐ´Ð¸Ñ ÐºÐ°Ðº обÑÑÐ½Ð°Ñ Ð¾ÑпÑавка ÑоÑмÑ.
ÐÑпÑавка пÑоÑÑой ÑоÑмÑ
ÐавайÑе ÑнаÑала оÑпÑавим пÑоÑÑÑÑ ÑоÑмÑ.
Ðак Ð²Ñ Ð²Ð¸Ð´Ð¸Ñе, код оÑÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð°ÐºÑнÑй:
<form id="formElem">
<input type="text" name="name" value="John">
<input type="text" name="surname" value="Smith">
<input type="submit">
</form>
<script>
formElem.onsubmit = async (e) => {
e.preventDefault();
let response = await fetch('/article/formdata/post/user', {
method: 'POST',
body: new FormData(formElem)
});
let result = await response.json();
alert(result.message);
};
</script>
Ð ÑÑом пÑимеÑе ÑеÑвеÑнÑй код не пÑедÑÑавлен, он за Ñамками ÑÑой ÑÑаÑÑи, он пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ POST-запÑÐ¾Ñ Ñ Ð´Ð°Ð½Ð½Ñми ÑоÑÐ¼Ñ Ð¸ оÑвеÑÐ°ÐµÑ ÑообÑением «ÐолÑзоваÑÐµÐ»Ñ ÑÐ¾Ñ ÑанÑн».
ÐеÑÐ¾Ð´Ñ Ð¾Ð±ÑекÑа FormData
С помоÑÑÑ ÑказаннÑÑ
ниже меÑодов Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ изменÑÑÑ Ð¿Ð¾Ð»Ñ Ð² обÑекÑе FormData:
formData.append(name, value)â добавлÑÐµÑ Ðº обÑекÑÑ Ð¿Ð¾Ð»Ðµ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼nameи знаÑениемvalue,formData.append(name, blob, fileName)â добавлÑÐµÑ Ð¿Ð¾Ð»Ðµ, как бÑдÑо в ÑоÑме имееÑÑÑ ÑлеменÑ<input type="file">, ÑÑеÑий аÑгÑменÑfileNameÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¸Ð¼Ñ Ñайла (не Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ ÑоÑмÑ), как бÑдÑо ÑÑо Ð¸Ð¼Ñ Ð¸Ð· Ñайловой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ,formData.delete(name)â ÑдалÑÐµÑ Ð¿Ð¾Ð»Ðµ Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñм именемname,formData.get(name)â полÑÑÐ°ÐµÑ Ð·Ð½Ð°Ñение Ð¿Ð¾Ð»Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼name,formData.has(name)â еÑли ÑÑÑеÑÑвÑÐµÑ Ð¿Ð¾Ð»Ðµ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼name, Ñо возвÑаÑаеÑtrue, инаÑеfalse
ТеÑ
ниÑеÑки ÑоÑма Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¼Ð½Ð¾Ð³Ð¾ полей Ñ Ð¾Ð´Ð½Ð¸Ð¼ и Ñем же именем name, поÑÑÐ¾Ð¼Ñ Ð½ÐµÑколÑко вÑзовов append добавÑÑ Ð½ÐµÑколÑко полей Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñми именами.
ÐÑÑ ÑÑÑеÑÑвÑÐµÑ Ð¼ÐµÑод set, его ÑинÑакÑÐ¸Ñ Ñакой же, как Ñ append. РазниÑа в Ñом, ÑÑо .set ÑдалÑÐµÑ Ð²Ñе Ñже имеÑÑиеÑÑ Ð¿Ð¾Ð»Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ name и ÑолÑко заÑем добавлÑÐµÑ Ð½Ð¾Ð²Ð¾Ðµ. То еÑÑÑ ÑÑÐ¾Ñ Ð¼ÐµÑод гаÑанÑиÑÑеÑ, ÑÑо бÑÐ´ÐµÑ ÑÑÑеÑÑвоваÑÑ ÑолÑко одно поле Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ name, в оÑÑалÑном он аналогиÑен .append:
formData.set(name, value),formData.set(name, blob, fileName).
ÐÐ¾Ð»Ñ Ð¾Ð±ÑекÑа formData можно пеÑебиÑаÑÑ, иÑполÑзÑÑ Ñикл for..of:
let formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
// СпиÑок Ð¿Ð°Ñ ÐºÐ»ÑÑ/знаÑение
for(let [name, value] of formData) {
alert(`${name} = ${value}`); // key1=value1, поÑом key2=value2
}
ÐÑпÑавка ÑоÑÐ¼Ñ Ñ Ñайлом
ÐбÑекÑÑ FormData вÑегда оÑÑÑлаÑÑÑÑ Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð¼ Content-Type: multipart/form-data, ÑÑÐ¾Ñ ÑпоÑоб кодиÑовки позволÑÐµÑ Ð¾ÑÑÑлаÑÑ ÑайлÑ. Таким обÑазом, Ð¿Ð¾Ð»Ñ <input type="file"> Ñоже оÑпÑавлÑÑÑÑÑ, как ÑÑо и пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð² ÑлÑÑае обÑÑной ÑоÑмÑ.
ÐÑÐ¸Ð¼ÐµÑ Ñакой ÑоÑмÑ:
<form id="formElem">
<input type="text" name="firstName" value="John">
ÐаÑÑинка: <input type="file" name="picture" accept="image/*">
<input type="submit">
</form>
<script>
formElem.onsubmit = async (e) => {
e.preventDefault();
let response = await fetch('/article/formdata/post/user-avatar', {
method: 'POST',
body: new FormData(formElem)
});
let result = await response.json();
alert(result.message);
};
</script>
ÐÑпÑавка ÑоÑÐ¼Ñ Ñ Blob-даннÑми
Ранее в главе Fetch Ð¼Ñ Ð²Ð¸Ð´ÐµÐ»Ð¸, ÑÑо оÑÐµÐ½Ñ Ð»ÐµÐ³ÐºÐ¾ оÑпÑавиÑÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑки ÑгенеÑиÑованнÑе бинаÑнÑе даннÑе в ÑоÑмаÑе Blob. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ Ñвно пеÑедаÑÑ ÐµÑ Ð² паÑамеÑÑ body запÑоÑа fetch.
Ðо на пÑакÑике бÑÐ²Ð°ÐµÑ Ñдобнее оÑпÑавлÑÑÑ Ð¸Ð·Ð¾Ð±Ñажение не оÑделÑно, а в ÑоÑÑаве ÑоÑмÑ, добавив дополниÑелÑнÑе Ð¿Ð¾Ð»Ñ Ð´Ð»Ñ Ð¸Ð¼ÐµÐ½Ð¸ и дÑÑгие меÑаданнÑе.
ÐÑоме Ñого, ÑеÑвеÑÑ ÑаÑÑо наÑÑÑÐ¾ÐµÐ½Ñ Ð½Ð° пÑиÑм именно ÑоÑм, а не пÑоÑÑо бинаÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ .
РпÑимеÑе ниже поÑÑлаеÑÑÑ Ð¸Ð·Ð¾Ð±Ñажение из <canvas> и еÑÑ Ð½ÐµÑколÑко полей, как ÑоÑма, иÑполÑзÑÑ FormData:
<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="ÐÑпÑавиÑÑ" onclick="submit()">
<script>
canvasElem.onmousemove = function(e) {
let ctx = canvasElem.getContext('2d');
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
};
async function submit() {
let imageBlob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
let formData = new FormData();
formData.append("firstName", "John");
formData.append("image", imageBlob, "image.png");
let response = await fetch('/article/formdata/post/image-form', {
method: 'POST',
body: formData
});
let result = await response.json();
alert(result.message);
}
</script>
</body>
ÐожалÑйÑÑа, обÑаÑиÑе внимание на Ñо, как добавлÑеÑÑÑ Ð¸Ð·Ð¾Ð±Ñажение Blob:
formData.append("image", imageBlob, "image.png");
ÐÑо как еÑли Ð±Ñ Ð² ÑоÑме бÑл ÑÐ»ÐµÐ¼ÐµÐ½Ñ <input type="file" name="image"> и полÑзоваÑÐµÐ»Ñ Ð¿ÑикÑепил Ð±Ñ Ñайл Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ "image.png" (3-й аÑгÑменÑ) и даннÑми imageBlob (2-й аÑгÑменÑ) из Ñвоей Ñайловой ÑиÑÑемÑ.
СеÑÐ²ÐµÑ Ð¿ÑоÑиÑÐ°ÐµÑ Ð¸ даннÑе и Ñайл, ÑоÑно Ñак же, как еÑли Ð±Ñ ÑÑо бÑла обÑÑÐ½Ð°Ñ Ð¾ÑпÑавка ÑоÑмÑ.
ÐÑого
ÐбÑекÑÑ FormData иÑполÑзÑÑÑÑÑ, ÑÑÐ¾Ð±Ñ Ð²Ð·ÑÑÑ Ð´Ð°Ð½Ð½Ñе из HTML-ÑоÑÐ¼Ñ Ð¸ оÑпÑавиÑÑ Ð¸Ñ
Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ fetch или дÑÑгого меÑода Ð´Ð»Ñ ÑабоÑÑ Ñ ÑеÑÑÑ.
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ ÑоздаÑÑ Ñакой обÑÐµÐºÑ Ñже Ñ Ð´Ð°Ð½Ð½Ñми, пеÑедав в конÑÑÑÑкÑÐ¾Ñ HTML-ÑоÑÐ¼Ñ â new FormData(form), или же можно ÑоздаÑÑ Ð¾Ð±ÑÐµÐºÑ Ð²Ð¾Ð¾Ð±Ñе без ÑоÑÐ¼Ñ Ð¸ заÑем добавиÑÑ Ðº Ð½ÐµÐ¼Ñ Ð¿Ð¾Ð»Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼ÐµÑодов:
formData.append(name, value)formData.append(name, blob, fileName)formData.set(name, value)formData.set(name, blob, fileName)
ÐÑмеÑим две оÑобенноÑÑи:
- ÐеÑод
setÑдалÑÐµÑ Ð¿ÑедÑдÑÑие Ð¿Ð¾Ð»Ñ Ñ Ñаким же именем, аappendâ неÑ. Ð ÑÑом Ð¸Ñ ÐµÐ´Ð¸Ð½ÑÑвенное оÑлиÑие. - ЧÑÐ¾Ð±Ñ Ð¿Ð¾ÑлаÑÑ Ñайл, нÑжно иÑполÑзоваÑÑ ÑинÑакÑÐ¸Ñ Ñ ÑÑÐµÐ¼Ñ Ð°ÑгÑменÑами, в каÑеÑÑве ÑÑеÑÑего как Ñаз ÑказÑваеÑÑÑ Ð¸Ð¼Ñ Ñайла, коÑоÑое обÑÑно, пÑи
<input type="file">, беÑÑÑÑÑ Ð¸Ð· Ñайловой ÑиÑÑемÑ.
ÐÑÑгие меÑодÑ:
formData.delete(name)formData.get(name)formData.has(name)
ÐÐ¾Ñ Ð¸ вÑÑ!
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)