Обработайте введенные данные для JS запроса Fetch Api, как jQuery делает в Ajax запросе, когда processData имеет значение true - PullRequest
1 голос
/ 25 марта 2020

Прежде всего. Код ajax_handler.php

<?php
$res = $_POST;
$res['response'] = 'Custom';
header('Content-Type: application/json');
echo json_encode($res);

У меня есть функция jQuery Ajax с оберткой Promise следующим образом.

const _sendAjax = async (url, params = {}, dataType = 'json', method = 'POST') => new Promise(async (accept, reject) => {
    if (url.trim().length < 1)
        return reject('Invalid Url');
    method = method.trim().toUpperCase();
    if (!['POST', 'GET'].includes(method))
        return reject('Invalid Ajax Method');
    let u = new URL(url, window.location.href);
    u.searchParams.set('upd', Math.random() * 1000 + new Date().getMilliseconds());
    url = u.toString();
    $.ajax({
        url: url,
        type: method,
        processData: true,
        dataType: dataType,
        data: params,
        success: data => accept(data),
        error: (request, status, error) => {
            reject({ request, status, error });
        }
    });
});

// Callings
_sendAjax('ajax_handler.php', { a: 22, b: 23 }).then(res => console.log(res)).catch(error => console.error(error));// {"a":"22","b":"23","response":"Custom"}

_sendAjax('ajax_handler.php', { a: [1, 2, 3, 4], b: 23 }).then(res => console.log(res)).catch(error => console.error(error));// {"a":["1","2","3","4"],"b":"23","response":"Custom"}

_sendAjax('ajax_handler.php', { a: { c: [1, 2, 3, 4], d: 45 }, b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":{"c":["1","2","3","4"],"d":"45"},"b":"23","response":"Custom"}

Ответы (соответственно)

console.log({"a":"22","b":"23","response":"Custom"});

console.log({"a":["1","2","3","4"],"b":"23","response":"Custom"});

console.log({"a":{"c":["1","2","3","4"],"d":"45"},"b":"23","response":"Custom"});

См. Изменение в представленных данных как params

Я пытался преобразовать эту функцию в JS Fetch Api .

const _sendFetch = async (url, params = {}, dataType = 'json', method = 'POST') => new Promise(async (accept, reject) => {
    if (url.trim().length < 1)
        return reject('Invalid Url');
    method = method.trim().toUpperCase();
    if (!['POST', 'GET'].includes(method))
        return reject('Invalid Ajax Method');
    let u = new URL(url, window.location.href);
    u.searchParams.set('upd', Math.random() * 1000 + new Date().getMilliseconds());
    let fetchOptions = {
        credentials: 'include',
        cache: 'no-store',
        redirect: 'follow',
        method: method,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        }
    }
    if (Object.keys(params).length)
        if (method === 'POST')
            fetchOptions.body = Object.keys(params).map(x => encodeURIComponent(x) + '=' + encodeURIComponent(params[x])).join('&');
        else if (method === 'GET')
            Object.keys(params).forEach(x => u.searchParams.set(encodeURIComponent(x), encodeURIComponent(params[x])));
    url = u.toString();
    return fetch(url, fetchOptions)
        .then(res => (res.status === 200 && res.ok) ? res : reject(res))
        .then(res => dataType === 'json' ? accept(res.json()) : accept(res.text()))
        .catch(error => reject(error));
});

// Callings
_sendFetch('ajax_handler.php', { a: 22, b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":"22","b":"23","response":"Custom"}

_sendFetch('ajax_handler.php', { a: [1, 2, 3, 4], b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":"1,2,3,4","b":"23","response":"Custom"}

_sendFetch('ajax_handler.php', { a: { c: [1, 2, 3, 4], d: 45 }, b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":"[object Object]","b":"23","response":"Custom"}

Ответы (соответственно)

console.log({"a":"22","b":"23","response":"Custom"});

console.log({"a":"1,2,3,4","b":"23","response":"Custom"});

console.log({"a":"[object Object]","b":"23","response":"Custom"});

Проблема:

Очевидно, я не могу обработать и отправить введенные данные как jQuery делает из-за processData: true,. jQuery, кажется, эффективно обрабатывает данные как для POST, так и для GET.

Я не могу найти способ воспроизвести работу processData функциональности jQuery Ajax, поскольку params имеет много вариантов, и мне нужен некоторый обобщенный код c для обработки введенных данных для Fetch как jQuery делает.

Я хочу сделать это в JS только без сторонних библиотек, таких как jQuery.

1 Ответ

0 голосов
/ 01 апреля 2020

Я упоминал, что мне нужно решение только в JS, но, как прокомментировал @CBore, у меня есть несколько вариантов в этом вопросе.

  1. Напишите свое собственное рекурсивная функция.
  2. Используйте URLSearchParams , как описано здесь . Но это не работает для моего сценария, так как параметры не просто объект.

console.log(new URLSearchParams({ a: { c: [1, 2, 3, 4], d: 45 }, b: 23 }).toString());
Используйте jQuery .param . Но я не хочу использовать полную библиотеку только для одной функции / преимущества. Используйте легковесную библиотеку, такую ​​как jquery -param .

Итак, в итоге я согласился на jquery -парам на данный момент.

...