Разработчики JavaScript часто ставят перед собой задачу отправить запросы GET и POST для получения или отправки данных. Есть библиотеки, такие как Axios, которые помогут вам сделать это с красивым синтаксисом. Однако вы можете добиться того же результата с очень похожим синтаксисом с Fetch API, который поддерживается во всех современных браузерах.

Используя Fetch API, вам не нужно устанавливать внешнюю библиотеку и, таким образом, уменьшать размер встроенного файла. И вы по-прежнему можете иметь красивый синтаксис с небольшим количеством кода. Давайте сделаем это!

Отправка запросов с помощью Fetch API

Чтобы отправить запрос GET с помощью Fetch API, используйте следующий код:

fetch( 'https://domain.com/path/?param1=value1&param2=value2' )
    .then( response => response.json() )
    .then( response => {
        // Do something with response.
    } );

Чтобы отправить запрос POST, используйте следующий код:

const params = {
    param1: value1,
    param2: value2; 
};
const options = {
    method: 'POST',
    body: JSON.stringify( params )  
};
fetch( 'https://domain.com/path/', options )
    .then( response => response.json() )
    .then( response => {
        // Do something with response.
    } );

Вы можете видеть, что основное различие между запросами GET и POST заключается в том, как параметры передаются в вызов fetch. В большинстве случаев разработчики ожидают передачи объекта параметров и отправки запросов в красивом синтаксисе, например:

const params = {
    param1: value1,
    param2: value2; 
};
const response = get( url, params );
// or
const response = post( url, params );

Для этого нам понадобится код для преобразования исходного кода с fetch в новый синтаксис.

Создание get и post функций

Поскольку коды отправки запросов в GET и POST схожи, мы создадим общую функцию request, которая будет делать запрос в первую очередь. А затем используйте его для создания таких функций get и post:

const request = ( url, params, method ) => {
    // All logic is here.
};
const get = ( url, params ) => request( url, params, 'GET' );
const post = ( url, params ) => request( url, params, 'POST' );

Пришло время создать функцию request.

Обратите внимание, что для каждой функции у нас есть свой способ создания параметров: они находятся в URL-адресе для GET и в теле для POST. Благодаря URLSearchParams мы можем преобразовать объект в строку запроса для запроса GET.

Вот первая версия:

const request = ( url, params = {}, method = 'GET' ) => {
    let options = {
        method
    };
    if ( 'GET' === method ) {
        url += '?' + ( new URLSearchParams( params ) ).toString();
    } else {
        options.body = JSON.stringify( params );
    }
    
    return fetch( url, options ).then( response => response.json() );
};
const get = ( url, params ) => request( url, params, 'GET' );
const post = ( url, params ) => request( url, params, 'POST' );

Приведенный выше код возвращает обещание, и вы можете использовать его в своем приложении следующим образом:

get( 'https://domain.com/path', { param1: value1, param2: value2 } )
.then( response => {
    // Do something with response.
} );

Вы можете увидеть это в действии на CodeSandbox.

Кеширование запросов

Одна из проблем, с которой обычно сталкиваются разработчики, - это кеширование запросов, чтобы один и тот же запрос не отправлялся несколько раз.

Чтобы реализовать кеширование, мы можем создать объект для хранения данных и использовать его для возврата данных ранее:

let cache = {};
const request = ( url, params = {}, method = 'GET' ) => {
    // Quick return from cache.
    let cacheKey = JSON.stringify( { url, params, method } );
    if ( cache[ cacheKey ] ) {
        return cache[ cacheKey ];
    }
    let options = {
        method
    };
    if ( 'GET' === method ) {
        url += '?' + ( new URLSearchParams( params ) ).toString();
    } else {
        options.body = JSON.stringify( params );
    }
    
    const result = fetch( url, options ).then( response => response.json() );
    cache[ cacheKey ] = result;
    return result;
};

WordPress REST API

Как разработчик WordPress я обычно работаю с WordPress REST API. Хотя приведенный выше код отлично работает в обычном приложении JavaScript, для его работы в WordPress требуются некоторые изменения.

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

let cache = {};
const request = ( url, params = {}, method = 'GET' ) => {
    let cacheKey = JSON.stringify( { url, params, method } );
    if ( cache[ cacheKey ] ) {
        return cache[ cacheKey ];
    }
    let options = {
        method,
        headers: { 'X-WP-Nonce': MyApp.nonce }, // Add nonce for WP REST API
    };
    // Setup the rest base URL for requests.
    url = `${ MyApp.restBase }/url`;
    if ( 'GET' === method ) {
        url += '?' + ( new URLSearchParams( params ) ).toString();
    } else {
        options.body = JSON.stringify( params );
    }
    
    const result = fetch( url, options ).then( response => response.json() );
    cache[ cacheKey ] = result;
    return result;
};

Чтобы отправить restBase и nonce в JavaScript, нам нужно использовать функцию wp_localize_script в PHP-файле вашего плагина или темы, как показано ниже:

wp_enqueue_script( 'my-app', plugin_dir_url( __FILE__ ) . 'js/app.js', [], '1.0', true );
wp_localize_script( 'my-app', 'MyApp', [
    'restBase' => untrailingslashit( rest_url() ),
    'nonce'    => wp_create_nonce( 'wp_rest' ),
] );

После этого вы можете делать такие запросы:

get( 'my-namespace/my-endpoint', { param1: value1, param2: value2 } )
.then( response => {
    // Do something with response.
} );

Заключение

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

Я также написал статью о модернизации JS-кода (улучшении и модернизации большой кодовой базы JavaScript). Так что, если вам интересно, вы можете прочитать его, чтобы получить лучший код.

Удачного кодирования!

— — —

Публикация в Meta Box.