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

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

Почему важна правильная отправка файлов в REST API WordPress

Передача файлов отличается от передачи обычных данных JSON. Обычно файл отправляется в формате multipart/form-data, а сервер должен корректно распарсить и сохранить этот файл, а также связать с нужной сущностью (например, с записью или пользователем). Неправильная обработка может привести к ошибкам загрузки, проблемам с безопасностью и некорректному отображению медиа.

В WordPress есть отдельный API для работы с медиа — функции wp_handle_upload(), wp_insert_attachment() и прочие, которые нужно использовать в обработчиках REST API для загрузки файлов.

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

Рассмотрим пример, как создать эндпоинт для загрузки изображения с привязкой к пользователю через POST запрос с multipart/form-data.

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

function wpapi_rest_upload_image(WP_REST_Request $request) {
    if (empty($_FILES['image'])) {
        return new WP_REST_Response(['error' => 'Файл не передан'], 400);
    }

    $file = $_FILES['image'];

    $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);

        // Прикрепим файл к текущему пользователю
        $user_id = get_current_user_id();
        update_user_meta($user_id, 'profile_image', $attach_id);

        return new WP_REST_Response(['attachment_id' => $attach_id, 'url' => wp_get_attachment_url($attach_id)], 200);
    } else {
        return new WP_REST_Response(['error' => $movefile['error']], 500);
    }
}

В этом примере мы создаем эндпоинт wpapi/v1/upload-image, который принимает POST запрос с файлом под ключом image. Файл загружается в медиабиблиотеку, создается вложение, а ID вложения сохраняется в метаполе пользователя как аватар.

Отправка изображения с помощью Postman или jQuery AJAX

Для тестирования эндпоинта удобно использовать Postman. В Body выбираем form-data, ключ image и загружаем файл. Не забудьте установить авторизационный заголовок, например, Bearer токен для авторизации.

Пример отправки через jQuery AJAX:

var formData = new FormData();
formData.append('image', fileInput.files[0]);

$.ajax({
    url: '/wp-json/wpapi/v1/upload-image',
    method: 'POST',
    data: formData,
    processData: false,
    contentType: false,
    beforeSend: function(xhr) {
        xhr.setRequestHeader('X-WP-Nonce', wpApiSettings.nonce); // если используется nonce
    },
    success: function(response) {
        console.log('Файл загружен', response);
    },
    error: function(err) {
        console.error('Ошибка загрузки', err);
    }
});

Обработка ошибок и безопасность при загрузке файлов

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

Кроме того, контролируйте типы файлов, чтобы не допустить загрузку опасных форматов. В WordPress по умолчанию запрещены некоторые расширения, но лучше явно проверять MIME типы.

Также важно ограничивать максимальный размер загружаемых файлов через настройки PHP и WordPress, чтобы избежать DoS-атак.

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

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

  • Clearfy Pro — содержит оптимизации безопасности и улучшения REST API.
  • WPRemark — позволяет расширять REST API комментариями и медиа.

Эти плагины помогут быстрее внедрить функционал с минимальным кодом.

Итоги и рекомендации

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

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

Для подробностей и примеров можно изучить документацию WordPress по медиа API и REST API, а также готовые решения на wpshop.ru.

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