WP REST API: отправка файлов и изображений в POST запросах

Одной из часто возникающих задач при работе с WP REST API является необходимость загружать и отправлять файлы, например изображения, вместе с POST-запросами. В стандартной реализации REST API WordPress нет готового универсального решения для загрузки файлов в кастомных эндпоинтах, поэтому в этой статье мы подробно рассмотрим, как можно организовать загрузку и обработку файлов через REST API, а также подключить необходимые фильтры и меры безопасности.

Особенности работы с файлами в WP REST API

По умолчанию, WP REST API не поддерживает передачу файлов как часть JSON-запроса. Для загрузки файлов обычно используется multipart/form-data — стандартный формат для передачи файлов через HTTP. Поэтому для работы с файлами в REST API нужно правильно настроить прием данных и обработку в PHP.

Кроме того, важно учитывать, что WordPress хранит загруженные медиафайлы через медиа-библиотеку, то есть для корректной загрузки нужно использовать функции WordPress для сохранения файлов в библиотеку и присвоения метаданных.

Типичные сценарии загрузки файлов через REST API включают:

  • Загрузка одного или нескольких изображений, прикрепление их к записи;
  • Загрузка документов (PDF, DOC и др.) и их сохранение;
  • Обработка ошибок загрузки и валидация типов файлов;
  • Авторизация и проверка прав пользователя на загрузку файлов.

Обработка multipart/form-data в REST API

Для приема multipart/form-data запросов в кастомных эндпоинтах необходимо в функции обработчика получить глобальный массив $_FILES. В отличие от стандартных JSON-запросов, где данные передаются в теле запроса, файлы загружаются отдельно и доступны именно в $_FILES.

При регистрации REST API эндпоинта через register_rest_route обратите внимание, что параметры запроса не передаются в callback-функцию напрямую, а доступны через объект WP_REST_Request. Для доступа к файлам используйте глобальный массив $_FILES.

Пример создания REST API эндпоинта для загрузки изображения

Ниже показан пример кода, который регистрирует кастомный REST API эндпоинт /wpapi/v1/upload-image, который принимает POST-запрос с файлом изображения и сохраняет его в медиа-библиотеку WordPress.

add_action('rest_api_init', function () {
    register_rest_route('wpapi/v1', '/upload-image', [
        'methods' => 'POST',
        'callback' => 'wpapi_handle_image_upload',
        'permission_callback' => function () {
            return current_user_can('upload_files');
        }
    ]);
});

function wpapi_handle_image_upload(WP_REST_Request $request) {
    if (empty($_FILES['file'])) {
        return new WP_Error('no_file', 'Файл для загрузки не найден', ['status' => 400]);
    }

    $file = $_FILES['file'];

    // Проверяем ошибки загрузки PHP
    if ($file['error'] !== UPLOAD_ERR_OK) {
        return new WP_Error('upload_error', 'Ошибка загрузки файла', ['status' => 400]);
    }

    // Используем функцию WordPress для обработки загрузки
    require_once(ABSPATH . 'wp-admin/includes/file.php');
    require_once(ABSPATH . 'wp-admin/includes/media.php');
    require_once(ABSPATH . 'wp-admin/includes/image.php');

    // Загрузка файла в папку uploads
    $attachment_id = media_handle_upload('file', 0);

    if (is_wp_error($attachment_id)) {
        return new WP_Error('upload_failed', 'Ошибка при сохранении файла в медиабиблиотеку', ['status' => 500]);
    }

    $attachment_url = wp_get_attachment_url($attachment_id);

    return [
        'success' => true,
        'attachment_id' => $attachment_id,
        'url' => $attachment_url
    ];
}

Этот код:

  • Проверяет, что в запросе присутствует файл с ключом file;
  • Использует встроенную функцию media_handle_upload для безопасной загрузки файла и создания вложения;
  • Возвращает ID вложения и URL загруженного файла в ответе API.

Как отправить файл через REST API — пример на JavaScript

Для тестирования загрузки файла в REST API удобно использовать JavaScript с Fetch API и FormData. Вот минимальный пример:

const fileInput = document.querySelector('#upload-file');
const formData = new FormData();
formData.append('file', fileInput.files[0]);

fetch('/wp-json/wpapi/v1/upload-image', {
  method: 'POST',
  body: formData,
  credentials: 'include', // для отправки cookie авторизации
  headers: {
    'X-WP-Nonce': wpApiSettings.nonce // если используете nonce для авторизации
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
<

Обратите внимание, что если на сайте включена проверка nonce (например, с помощью wp_localize_script), то нужно передавать X-WP-Nonce в заголовках для авторизации.

Валидация и безопасность при загрузке файлов

Очень важно провести проверку типа и размера файла, чтобы не допустить загрузку вредоносных файлов или слишком больших ресурсов.

Для этого можно использовать фильтр wp_handle_upload_prefilter, который позволяет отфильтровать файлы до загрузки:

add_filter('wp_handle_upload_prefilter', function($file) {
    $allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($file['type'], $allowed_types)) {
        $file['error'] = 'Разрешены только изображения JPG, PNG, GIF';
    }

    if ($file['size'] > 2 * 1024 * 1024) { // ограничение 2Мб
        $file['error'] = 'Размер файла не должен превышать 2Мб';
    }
    return $file;
});
<

Также рекомендуется проверять права пользователя с помощью current_user_can('upload_files'), как показано в примере выше.

Использование плагинов для расширения возможностей загрузки через REST API

Если не хочется писать обработчик с нуля, можно воспользоваться популярными плагинами, которые расширяют REST API для загрузки файлов:

  • REST API Upload — добавляет поддержку загрузки файлов через REST API с проверкой и сохранением в медиабиблиотеку;
  • Clearfy Pro — плагин оптимизации, который содержит ряд улучшений безопасности и может помочь в настройке REST API;
  • Плагин WPRemark позволяет создавать расширенные комментарии и может быть полезен для работы с кастомными типами записей и файлами.

Как интегрировать эти плагины

Обычно достаточно установить и активировать плагин, после чего в REST API добавляется поддержка загрузки файлов. Некоторые плагины предоставляют свои эндпоинты или расширяют существующие. Рекомендуется ознакомиться с документацией каждого из них для правильного использования.

Подводим итоги и советы по реализации

Загрузка файлов и изображений через WP REST API — задача, требующая аккуратного подхода:

  • Используйте multipart/form-data для передачи файлов;
  • Обрабатывайте файлы через глобальный массив $_FILES и функции WordPress для загрузки и сохранения;
  • Проверяйте права пользователя и валидацию файлов (тип, размер);
  • Возвращайте понятные ошибки для клиента;
  • При необходимости используйте готовые плагины для ускорения разработки.

Подробнее о загрузке и работе с REST API можно прочитать в официальной документации WordPress и на специализированных ресурсах. Надеюсь, примеры и советы из этой статьи помогут вам реализовать надежный и удобный функционал загрузки файлов через WP REST API.

Шаблоны для WP Плагины для WP