fetch是怎么取代ajax的?

fetch 简介

  • Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
  • 这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案,可以很容易地被其他技术使用,例如 Service Workers (en-US)。Fetch 还提供了专门的逻辑空间来定义其他与 HTTP 相关的概念,例如 CORS 和 HTTP 的扩展。

fetch 规范与 jQuery.ajax() 主要有三种方式的不同

当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject, 即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
fetch() 可以不会接受跨域 cookies;你也可以不能使用 fetch() 建立起跨域会话。其他网站的 Set-Cookie 头部字段将会被无视。
fetch 不会发送 cookies。除非你使用了credentials 的初始化选项。(自 2017 年 8 月 25 日以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改)

------------以上不同来自官网

个人觉得它相对比ajax结构要清晰,在then中首先是处理response ,然后是response内部也提供了数据json格式化(response.json());还有一点 它更像面向对象的编程了,一位request/Headers可以实例化对象,并配置属性 。
例如:


var myHeaders = new Headers();

myHeaders.append("Content-Type", "text/plain");

像response也提供较丰富的api:
file

非浏览器里面使用Fetch

如果要在不支持的浏览器中使用 Fetch,可以使用 Fetch Polyfill,这个就是typescripe的标准,下载npm进行安装fetch环境即可使用

file

浏览器的兼容性

file

封装fetch

调用封装的fetch

这部分发现返回的响应体必须是个json格式,单纯的字符串 数值等 会出现问题

    //获取列表信息
        function getList(){
            F_Request.getRequest('http://localhost:8080/list', null, function(data) {
                document.getElementById("content").innerText = JSON.stringify(data);
                console.log(data);
            }, function(error) {
                console.log(error);
            });
            
        }

        //上传请求
        function uploadFile() {
            //upload 是name值  file 是后台接收 参数的值
            F_Request.uploadFileRequest("upload","file", {
                userName: '李四',
                age: 15
            }, 'http://localhost:8080/uploadMul', null, function(data) {
                console.log("上传成功:");
                console.log(data);
            }, function(error) {
                console.log("上传失败");
            });
        }

个人封装的fetch( get 和post请求 已经验证过,包括多文件上传,也有java的部分后台代码)


var F_Request = {
    getRequest: function(url, initParams, successFunc = null, errorFunc = null) {
        /**
         * get请求
         */
        initParams = initParams ? initParams : {};
        initParams = Object.assign(initParams, {
            method: "GET"
        });
        this.RequestData(url, initParams, successFunc, errorFunc);
    },
    postRequest: function(url, initParams, successFunc = null, errorFunc = null) {

        initParams = initParams ? initParams : {};
        initParams = Object.assign(initParams, {
            method: "POST"
        });
        this.RequestData(url, initParams, successFunc, errorFunc);
    },
    putRequest: function(url, initParams, successFunc = null, errorFunc = null) {
        //put请求
        initParams = initParams ? initParams : {};
        initParams = Object.assign(initParams, {
            method: "PUT"
        });
        this.RequestData(url, initParams, successFunc, errorFunc);
    },
    uploadFileRequest: function(fileName = "upload", fileKey = "file", otherParams = {}, url, initParams,
        successFunc = null, errorFunc = null) {
        //上传文件 [支持多个文件上传]

        var formData = new FormData();
        var photos = document.querySelector("input[name='" + fileName + "'][multiple]");

        for (var param in otherParams) {
            formData.append(param, otherParams[param]);
        }

        // formData 只接受文件、Blob 或字符串,不能直接传递数组,所以必须循环嵌入
        for (let i = 0; i < photos.files.length; i++) {
            formData.append(fileKey, photos.files[i]);
        }


        initParams = initParams ? initParams : {};
        initParams.body = formData;
        initParams.method = initParams.method ? initParams.method : "POST";

        this.postRequest(url, initParams, successFunc, errorFunc);
    },
    deleteRequest: function(url, initParams, successFunc = null, errorFunc = null) {
        /**
         * delete请求
         */
        initParams = initParams ? initParams : {};
        initParams = Object.assign(initParams, {
            method: "DELETE"
        });
        this.RequestData(url, initParams, successFunc, errorFunc);
    },
    RequestData: function (url, initParams, successFunc = null, errorFunc = null) {

        /**
         * 请求实现方法
         */
        var defaultInitParams = {
            cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
            credentials: 'same-origin', // include (发送带凭据的请求), same-origin, *omit 
            /* headers: {
                'user-agent': 'Mozilla/4.0 MDN Example',
                'content-type': 'application/json'
            }, */
            method: 'GET', // *GET, POST, PUT, DELETE, etc.
            //mode: 'cors', // no-cors, cors, *same-origin
            redirect: 'follow', // manual, *follow, error
            referrer: 'no-referrer', // *client, no-referrer
        };

        //如果请求方法为GET 和 HEAD 就去除body信息
        if (defaultInitParams.method == 'GET' || defaultInitParams.method == 'HEAD') {
            delete defaultInitParams.method;
        }

        if (initParams.method == 'GET' || initParams.method == 'HEAD') {
            delete initParams.method;
        }


        defaultInitParams = Object.assign(defaultInitParams, initParams);

        fetch(
                url, defaultInitParams
            )
            .then(function(response) {
                //先只处理响应状态正常的
                if (response.status === 200) {
                    return response.json();
                }
                return {
                    error: 300
                };
            }).then(function(response) {
                //并没有返回信息
                if (response.error == 300) {
                    console.log("---请检查fetch的相关配置是否有问题---");
                    return;
                }

                if (typeof(successFunc) == "function") {
                    successFunc(response);
                }

            }).catch(function(error) {
                if (typeof(errorFunc) == "function") {
                    errorFunc(error)
                }
            });

    }

}

[完整代码](https://gitee.com/ten-ken/style-script/tree/master/fetch%E7%9A%84%E4%BD%BF%E7%94%A8(%E5%8F%96%E4%BB%A3ajax)

file

欢迎关注我的公众号:程序员ken,程序之路,让我们一起探索,共同进步。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容