Загрузка изображений — одна из ключевых функций для любого сайта на WordPress. Встроенный медиабиблиотекарный механизм подходит для большинства задач, но иногда требуется более гибкое решение: например, загрузчик с поддержкой Ajax для ускорения работы и улучшения UX. В этой статье мы подробно разберём, как создать собственный загрузчик изображений в WordPress, который работает через Ajax, с примером кода и рекомендациями по безопасности.
Почему стоит использовать собственный загрузчик изображений с Ajax в WordPress
Стандартная загрузка файлов в WordPress зачастую сопровождается перезагрузкой страницы, что не всегда удобно для пользователей. Ajax-загрузчик позволяет отправлять файлы на сервер асинхронно, без перезагрузки, улучшая взаимодействие с интерфейсом.
Также свой загрузчик даёт возможность более тонко контролировать процесс: например, добавлять ограничения по размеру и типам файлов, создавать пользовательские сообщения об ошибках, интегрировать дополнительные поля, и сразу получать обратную связь.
Кроме того, использование Ajax снижает нагрузку на сервер, так как нет необходимости обрабатывать полный запрос страницы, только обработка файла.
Основные этапы создания Ajax загрузчика
1. Создание HTML формы загрузки
Для начала создадим простую HTML форму с полем для выбора файла и кнопкой загрузки. Важно добавить enctype="multipart/form-data" и идентификатор для обращения через JavaScript.
<form id="wpgen-image-upload-form" enctype="multipart/form-data">
<input type="file" name="wpgen_image_file" accept="image/*" required />
<button type="submit">Загрузить изображение</button>
<div id="wpgen-upload-result"></div>
</form>2. Подключение JavaScript для отправки Ajax-запроса
Далее добавим JavaScript, который перехватит отправку формы, соберёт данные и отправит их на сервер через Ajax. В WordPress рекомендуется использовать встроенный объект wp.ajax или jQuery.ajax, но для простоты используем fetch API.
document.getElementById('wpgen-image-upload-form').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const resultDiv = document.getElementById('wpgen-upload-result');
resultDiv.textContent = 'Загрузка...';
fetch(wpgen_vars.ajax_url, {
method: 'POST',
credentials: 'same-origin',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.success) {
resultDiv.innerHTML = `Изображение загружено: <img src="${data.data.url}" style="max-width:200px;" />`;
} else {
resultDiv.textContent = 'Ошибка: ' + data.data.message;
}
})
.catch(() => {
resultDiv.textContent = 'Произошла ошибка при загрузке.';
});
});Обратите внимание, что в примере используется переменная wpgen_vars.ajax_url, которую нужно определить в PHP и передать в JavaScript для корректной работы.
3. Обработка загрузки на стороне сервера
Теперь создадим PHP обработчик, который примет файл, проверит его и загрузит в медиабиблиотеку WordPress, вернув JSON ответ.
add_action('wp_ajax_wpgen_upload_image', 'wpgen_upload_image_handler');
add_action('wp_ajax_nopriv_wpgen_upload_image', 'wpgen_upload_image_handler');
function wpgen_upload_image_handler() {
// Проверяем nonce для безопасности
if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wpgen_image_upload_nonce') ) {
wp_send_json_error(['message' => 'Ошибка безопасности.']);
}
if (empty($_FILES['wpgen_image_file'])) {
wp_send_json_error(['message' => 'Файл не загружен.']);
}
$file = $_FILES['wpgen_image_file'];
// Проверяем тип файла
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($file['type'], $allowed_types)) {
wp_send_json_error(['message' => 'Недопустимый тип файла.']);
}
// Используем встроенную функцию WordPress для загрузки
require_once(ABSPATH . 'wp-admin/includes/file.php');
$overrides = ['test_form' => false];
$movefile = wp_handle_upload($file, $overrides);
if ($movefile && !isset($movefile['error'])) {
$filename = $movefile['file'];
$filetype = wp_check_filetype(basename($filename), null);
$attachment = [
'post_mime_type' => $filetype['type'],
'post_title' => sanitize_file_name(basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
];
$attach_id = wp_insert_attachment($attachment, $filename);
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($attach_id, $filename);
wp_update_attachment_metadata($attach_id, $attach_data);
$url = wp_get_attachment_url($attach_id);
wp_send_json_success(['url' => $url]);
} else {
wp_send_json_error(['message' => $movefile['error']]);
}
}Подключение скриптов и локализация переменных
Чтобы JavaScript работал корректно, нужно зарегистрировать и подключить скрипт, а также передать переменную ajax_url и nonce для безопасности.
function wpgen_enqueue_scripts() {
wp_enqueue_script('wpgen-image-uploader', get_template_directory_uri() . '/js/wpgen-image-uploader.js', ['jquery'], null, true);
wp_localize_script('wpgen-image-uploader', 'wpgen_vars', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpgen_image_upload_nonce')
]);
}
add_action('wp_enqueue_scripts', 'wpgen_enqueue_scripts');В JavaScript следует добавить nonce в FormData перед отправкой:
formData.append('action', 'wpgen_upload_image');
formData.append('nonce', wpgen_vars.nonce);Советы по безопасности и улучшению
Важно тщательно проверять типы загружаемых файлов, чтобы избежать загрузки вредоносного кода. В примере мы ограничили типы только изображениями JPEG, PNG и GIF.
Также можно добавить проверку размера файла и ограничить его, например, 2 МБ:
if ($file['size'] > 2 * 1024 * 1024) {
wp_send_json_error(['message' => 'Размер файла превышает 2 МБ.']);
}Для более удобной работы с загрузчиком можно интегрировать его с популярными плагинами, например, Clearfy Pro для оптимизации безопасности, или WPRemark для быстрой модерации загруженных изображений.
Выводы и дальнейшие улучшения
Созданный загрузчик изображений с поддержкой Ajax позволит улучшить UX вашего сайта, ускорить работу с медиа и повысить безопасность. В дальнейшем можно расширять функционал, добавляя предпросмотр, множественную загрузку, прогресс-бар и интеграцию с REST API.
Для примера реализации с REST API рекомендуем изучить статью «Как создать собственный REST API endpoint в WordPress».