javascript - JQuery Ajax 获取转换说明

标签 javascript jquery ajax fetch

我的项目中有一个 ajax 包装函数。我将调用此包装函数在我的应用程序中执行 ajax 请求。现在我打算将其更改为使用 fetch。但由于我是新来的,我心里有一些问题。我相信这个问题对计划从 Jquery Ajax 迁移到 Fetch 的人有帮助。这是代码和问题。

我的旧 Jquery Ajax 包装函数:

function ajaxGetAsync(requestUrl, postData, global, datatype) {
    try {
        var form = $('#__AjaxAntiForgeryForm');
        var token = $('input[name="__RequestVerificationToken"]', form).val();
        return $.ajax({
            type: "GET",
            cache: false,
            contentType: "application/json; charset=utf-8",
            dataType: datatype,
            url: requestUrl,
            async: true,
            global: global,
            headers: {
                "XSRF-TOKEN": $('#_AjaxAntiForgeryTokenForm input[name="__RequestVerificationToken"]').val()
            },
            data: postData,
            error: function (jqXhr, textStatus, errorThrown) {
                console.log(jqXhr);

                handleShowInformationBox('Error', errorThrown, 'OK');
            }
        });
    } catch (q) {
        ajaxIndicatorStop();
    }

    return false;
};

function ajaxFormPostAsync(requestUrl, form, global = true) {
    try {
        return $.ajax({
            type: "POST",
            url: requestUrl,
            async: true,
            global: global,
            headers: {
                "XSRF-TOKEN": $('#_AjaxAntiForgeryTokenForm input[name="__RequestVerificationToken"]').val()
            },
            data: new URLSearchParams(new FormData(document.querySelector(form))).toString(),
            success: function () {
                handleHideValidationErrors(form);
            },
            error: function (jqXhr, textStatus, errorThrown) {
                console.log(jqXhr);

                handleShowInformationBox('Error', errorThrown, 'OK');
            }
        });
    } catch (q) {
        ajaxIndicatorStop();
    }

    return false;
};

下面是我如何配置 Ajax Globals 来显示/隐藏加载器:

$(document).ajaxStart(function () {
    ajaxIndicatorStart('Loading');
});

$(document).ajaxStop(function () {
    ajaxIndicatorStop();
});

现在我调用上面的方法从服务器获取 HTML/JSON,如下所示,

$.when(ajaxGetAsync(url, { id: Id }, true, window.htmlDataType)).done((response) => {
      document.querySelector('#someDiv').innerHTML = response;                                
});

$.when(ajaxPostAsync(url, { id: Id }, true, window.jsonDataType)).done((response) => {
      console.log(response);                               
});

请注意,我会将数据类型更改为 window.jsonDataType 以获取 json 数据。同样,我调用我的 ajaxFormPostAsync 这很好用。

这是获取等效项:

我的新 Fetch 包装函数:

async function fetchGetAsync(requestUrl, postData, global, dataType) {
    return await fetch(requestUrl,
        {
            method: 'GET',
            cache: 'no-cache',
            headers: {
                'Content-Type': 'application/json; charset=utf-8',
                "XSRF-TOKEN": $('#_AjaxAntiForgeryTokenForm input[name="__RequestVerificationToken"]').val()
            },
            body: postData
        }
    ).catch(function (error) {
        console.log(error);
        handleShowInformationBox('Error', error, 'OK');
    });
}

async function fetchFormPostAsync(requestUrl, form, global) {
    return await fetch(requestUrl,
        {
            method: 'POST',
            cache: 'no-cache',
            headers: {
                "XSRF-TOKEN": $('#_AjaxAntiForgeryTokenForm input[name="__RequestVerificationToken"]').val()
            },
            body: new FormData(document.querySelector(form))
        })
        .then(function (response) {
            return response.json();
        })
        .catch(function (error) {
            handleShowInformationBox('Error', error, 'OK');
        });
}

如何配置全局变量来显示/隐藏加载器? 如何在 fetch api 中指定数据类型?

我试着调用上面的方法如下,

await fetchGetAsync(url, { id: Id }, true, window.htmlDataType).then((response) => {
     document.querySelector('#someDiv').innerHTML = response;                                
})

await fetchFormPostAsync(url, targetForm).then(function (response) {
     console.log(response);            
});

这会引发错误,如下所示:

对于获取:

TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.

对于 POST:

Unexpected end of JSON input

如何像我以前那样使用fect api获取Json/Html?

刚开始使用我现有的代码学习 fetach api。请协助我哪里出错了。

最佳答案

经过一些学习和工作,下面是我如何在我的项目中实现 fetch API 包装器以及显示/隐藏微调器和删除 ajax 包装器。

获取 GET 包装器:

async function fetchGetAsync(requestUrl, postData, global, dataType) {
    let query = Object.keys(postData)
        .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(postData[k]))
        .join('&');
    requestUrl = `${requestUrl}?${query}`;

    if (global) ajaxIndicatorStart('Loading');

    return await fetch(requestUrl,
        {
            method: 'GET',
            cache: 'no-cache',
            headers: {
                "XSRF-TOKEN": document.querySelector('input[name="__RequestVerificationToken"]').value
            }
        })
        .then((response) => {
            return dataType === window.constant.jsonDataType ? response.json() : response.text();
        })
        .catch((error) => {
            handleShowDefaultInformationBox(error, 'OK');
        })
        .finally(() => {
            if (global) ajaxIndicatorStop();
        });
}

获取 POST 包装器:

async function fetchFormPostAsync(requestUrl, form, global = true) {
    if (global) ajaxIndicatorStart('Loading');

    return await fetch(requestUrl,
        {
            method: 'POST',
            cache: 'no-cache',
            headers: {
                "XSRF-TOKEN": document.querySelector('input[name="__RequestVerificationToken"]').value
            },
            body: new URLSearchParams(new FormData(document.querySelector(form)))
        })
        .then((response) => {
            return response.json();
        })
        .catch((error) => {
            handleShowDefaultInformationBox(error, 'OK');
        })
        .finally(() => {
            if (global) ajaxIndicatorStop();
        });
}

类似地,您可以为其他 HTTP 动词和操作构造 fetch API 包装器。

然后从您的 javascript 调用,如下所示:

调用 Fetch GET 包装器:

await fetchGetAsync(url, { id: Id }, true, window.constant.htmlDataType).then((response) => {
      document.querySelector('#someDiv').innerHTML = response;                                
})

调用 Fetch POST 包装器:

await fetchFormPostAsync(url, targetForm).then((response) => {
     console.log(response);            
});

感谢charlietflIcepickle 寻求指导和支持。

关于javascript - JQuery Ajax 获取转换说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58078804/

相关文章:

javascript - 获取 .txt 文件的内容并循环结果

javascript - 如何使用ajax函数更新数据库

javascript - phonegap - 在智能手机上获取默认音乐文件夹的跨平台方式

javascript - 即使 promise 为 200,也无法从刷新 token 生成新的访问 token

javascript - Dropzone Js max 文件上传无法正常工作

javascript - ExternalInterface.addCallback 无法正常工作

jquery UI 对话框在 IE7 中打开速度非常慢

javascript - JavaScript 中延迟加载的最佳实践

javascript - 如何在方法链中间设置断点

javascript - jQuery.get - 如何获取文本而不是 html?