Работа с формой через метод ajax и FormData
Объект FormData можно использовать в методе библиотеки jQuery ajax
.
Для этого методу $.ajax
необходимо установить следующие параметры:
processData: false,
contentType: false,
Параметр processData
со значением false
предотвратит автоматическое преобразование данных FormData в строку запроса. А параметр contentType
со значением false
запретит jQuery устанавливать заголовок Content-Type
и оставит это действие объекту XMLHttpRequest
. Установка этих параметров позволит предотвратить преобразование данных, закодированных объектом FormData
и установку неверного заголовка (application/x-www-form-urlencoded).
Разработку этого примера начнём с создания HTML формы и контейнера для вывода результата:
<div class="container">
<div class="panel panel-danger">
<div class="panel-heading">Данные, которые пришли с сервера:</div>
<!-- Контейнер для вывода результата (id = "result") -->
<div class="panel-body" id="result"></div>
</div>
<!-- HTML форма, данные которой будем отправлять на сервер по технологии AJAX (id="message") -->
<form id="message">
<div class="form-group">
<label for="name">Имя:</label>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group">
<label for="name">Сообщение:</label>
<textarea class="form-control" rows="3" name="message"></textarea>
</div>
<button id="send-message" class="btn btn-primary">Отправить сообщение</button>
</form>
</div>
PHP сценарий, который будет формировать ответ клиенту в формате JSON. Для создания ответа будем использовать ключи name
и message
суперглобального массива POST:
<?php
// если в массиве $_POST есть ключ name и его значение не равно пустоте, то
if ((isset($_POST['name'])) && (!empty($_POST["name"]))) {
// присвоить $result['name'] значение $_POST['name']
$result['name'] = $_POST['name'];
} else {
// иначе, $result['name'] присвоить указанную строку
$result['name'] = 'Вы не ввели поле name!';
}
// если в массиве $_POST есть ключ message и его значение не равно пустоте, то
if ((isset($_POST['message']))&& (!empty($_POST["message"]))) {
// присвоить $result['message'] значение $_POST['message']
$result['message'] = $_POST['message'];
} else {
// иначе, $result['message'] присвоить указанную строку
$result['message'] = 'Вы не ввели поле message!';
}
// преобразовать массив $result в json, а затем вывести его с помощью echo
echo json_encode($result);
Сам скрипт:
<script>
// после загрузки страницы
$(function() {
// при нажатии на кнопку "Отправить"
$('#message').submit(function(e) {
// создадим объект FormData и добавим в него данные из формы
var formData = new FormData($('#message')[0]);
// ajax-запрос (пример использования formdata в jquery):
// url - адрес на который будет отправлен запрос
// data - данные, которые необходимо отправить на сервер
// processData - отменить обработку данных
// contentType - не устанавливать заголовок Content-Type
// type - тип запроса
// dataType - тип данных ответа сервера
// success - функция, которая будет выполнена после удачного запроса
$.ajax({
url: 'process.php',
data: formData,
processData: false,
contentType: false,
type: 'POST',
dataType: 'JSON',
success: function(data) {
var output = '<ul>';
$.each(data, function(key, value) {
output += '<li><b>' + key + "</b>: " + value + '</li>';
});
output += '</ul>';
$('#result').html(output);
}
});
// отменяем отправку формы стандартным способом
e.preventDefault();
});
});
</script>
Отправка объекта FormData с файлом
Рассмотрим ещё один пример, в котором объект FormData будем использовать для отправки файла на сервер.
HTML-код, состоящий из блока div
с id="result"
, элемента input
с типом file
и кнопки для отправки файла на сервер:
<div class="container">
<!-- Блок, в который будем выводить путь к файлу на сервере -->
<p class="alert alert-info">
Результат:<br><span id="result"></span>
</p>
<div class="form-group">
<!-- Элемент, для выбора файла -->
<input type="file" id="file">
</div>
<!-- Элемент для отправки файла на сервер -->
<button id="upload-image" class="btn btn-primary">Отправить</button>
</div>
Сценарий php, выполняющий загрузку файла в указанную директорию:
<?php
// переменная для хранения результата
$result = 'Файл не был успешно загружен на сервер';
// путь для загрузки файлов
$upload_path = dirname(__FILE__) . '/uploads/';
// если файл был успешно загружен, то
if ($_FILES['file']['error'] == UPLOAD_ERR_OK) {
// получаем расширение исходного файла
$extension_file = mb_strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
// получаем уникальное имя под которым будет сохранён файл
$full_unique_name = $upload_path . uniqid('file_', true).'.'.$extension_file;
// перемещает файл из временного хранилища в указанную директорию
if (move_uploaded_file($_FILES['file']['tmp_name'], $full_unique_name)) {
// записываем в переменную $result ответ
$result = 'Файл загружен и доступен по адресу: <b>/' . substr($full_unique_name, strlen($_SERVER['DOCUMENT_ROOT'])+1) . '</b>';
} else {
// записываем в переменную $result сообщение о том, что произошла ошибка
$result = "Произошла обшибка при загрузке файла на сервер";
}
}
// возвращаем результат (ответ сервера)
echo $result;
JavaScript сценарий:
<script>
// после загрузки страницы
$(function() {
// при нажатии на кнопку "Отправить"
$('#upload-image').click(function() {
// элемент, с помощью которого пользователь выбирает файл
var file = $('#file');
// элемент, в который выведим ответ сервера
var result = $('#result');
// если файл выбран, то
if (file.prop('files').length) {
// создаём объект FormData
var formData = new FormData();
// добавляем в объект FormData файл
formData.append('file', file.prop('files')[0]);
// выполняем HTTP (AJAX) запрос
// url - адрес, содержащий php скрипт, который будет обрабатывать запрос
// procedData - параметр, с помощью которого отключим преобразование данных в строку запроса
// contentType - параметр, с помощью которого отключим установления типа контента jQuery
// type - параметр, с помощью которого установим в качестве метода отправки запроса POST
// success - параметр, который
$.ajax({
url: 'process.php',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function(data) {
result.html(data);
}
});
} else {
result.html("Не выбран файл для загрузки!");
}
});
});
</script>