Если вы разрабатываете одностраничное приложение или практикуете методы прогрессивного улучшения, вам часто нужно будет перехватывать отправку форм и переводить их в вызов Ajax. Давайте посмотрим на типичную форму:
<form id="myform" action="webservice.php" method="post">
<input type="email" name="email" />
<select name="job">
<option value="">role</option>
<option>web developer</option>
<option>IT professional</option>
<option>other</option>
</select>
<input type="checkbox" name="freelancer" /> are you a freelancer?
<input type="radio" name="experience" value="4" /> less than 5 year's experience
<input type="radio" name="experience" value="5" /> 5 or more year's experience
<textarea name="comments" rows="3" cols="60"></textarea>
<button type="submit">Submit</button>
</form>
Перехват формы в jQuery прост, потому что вы можете передать узел формы методу serialize
$("myform").on("submit", function(e) {
e.preventDefault();
$.post(this.action, $(this).serialize());
});
Если вы используете сырой JavaScript, вам нужно реализовать аналогичную функциональность самостоятельно. Вы можете вручную извлекать каждое поле одно за другим или реализовать общий цикл извлечения данных элемента формы:
document.getElementById("myform").onsubmit = function(e) {
e.preventDefault();
var f = e.target,
formData = '',
xhr = new XMLHttpRequest();
// fetch form values
for (var i = 0, d, v; i < f.elements.length; i++) {
d = f.elements[i];
if (d.name && d.value) {
v = (d.type == "checkbox" || d.type == "radio" ? (d.checked ? d.value : '') : d.value);
if (v) formData += d.name + "=" + escape(v) + "&";
}
}
xhr.open("POST", f.action);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(formData);
}
Это разумное количество кода, даже если вы определяете его в многократно используемой функции. Вам также могут потребоваться дополнительные проверки, если вы отключили поля или сделали их доступными только для чтения.
К счастью, малоизвестный интерфейс FormData
Давайте перепишем наш обработчик отправки JavaScript, чтобы использовать его:
document.getElementById("myform").onsubmit = function(e) {
e.preventDefault();
var f = e.target,
formData = new FormData(f),
xhr = new XMLHttpRequest();
xhr.open("POST", f.action);
xhr.send(formData);
}
Это намного проще — это также быстрее и проще для чтения, чем альтернатива jQuery.
В конструктор FormData
это дает команду извлекать и кодировать все пары имя / значение поля. Вы также заметите, что нам не нужно явно устанавливать xhr.setRequestHeader("Content-Type")
submit()
Кодировка multipart/form-data
Если элемент конструктора не передается, создается пустой объект FormData
Каким бы образом он ни инициализировался, вы можете добавлять дополнительные пары имя / значение, используя метод append
var formData = new FormData();
formData.append("name", "value");
formData.append("a", 1);
formData.append("b", 2);
Если значением является File или Blob, третий параметр может указать необязательное имя файла.
FormData
Только IE9 и ниже вызовут проблемы, но, если вы поддерживаете более старые версии IE, вы, вероятно, будете использовать jQuery или другую библиотеку, которая реализует свой собственный метод извлечения полевых данных.
Для получения дополнительной информации обратитесь к ссылке FormData и Использование объектов FormData на MDN.