如何使用 fetch ,加請(qǐng)求頭, ajax 和 fetch 和 axios 的區(qū)別

----歡迎查看我的博客----

什么是fetch

??我們之前未状,過(guò)度過(guò)來(lái)都在用ajax俯画,那么什么是 Fetch ,F(xiàn)etch 是新的游覽器對(duì)象, 等同于 XMLHttpRequest對(duì)象 司草。它提供了許多與 XMLHttpRequest 相同的功能艰垂,但被設(shè)計(jì)成更具可擴(kuò)展性和高效性。

image

ajax

??廢話不多說(shuō)我們來(lái)看一下傳統(tǒng)的ajax埋虹。

var xhr;
if (window.XMLHttpRequest) {
   xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
   try {
     xhr = new ActiveXObject('Msxml2.XMLHTTP');
   } catch (e) {
     try {
       xhr = new ActiveXObject('Microsoft.XMLHTTP');
     } catch (e) {}
   }
}
if (xhr) {
   xhr.onreadystatechange = () =>{
       if (xhr.readyState === 4) {
          if (xhr.status === 200) {
             console.log(xhr.responseText); //返回值傳callback
          } else {
                //failcallback
             console.log('There was a problem with the request.');
          }
       } else {
          console.log('still not ready...');
       }
    };
   xhr.open('POST', 'https://www.baidu.com', true);
   // 設(shè)置 Content-Type 為 application/x-www-form-urlencoded
   // 以表單的形式傳遞數(shù)據(jù)
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   xhr.send('username=admin&password=root');
}

??好我們來(lái)做層封裝猜憎,讓他變成我們 jQuery 的 ajax post
如這種形式:

$.ajax({
    method: 'POST', //請(qǐng)求方式
    url: '/api', //url
    data: { username: 'admin', password: 'root' }, //值
    success:function(data){ //成功回掉
        console.log(data)
    },
    error:function(err){
        console.log(err)
    }
})

好的封裝開始:

const $ = {};
$.ajax = (obj)=>{
    var xhr;
    if (window.XMLHttpRequest) {
       xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
       try {
         xhr = new ActiveXObject('Msxml2.XMLHTTP');
       } catch (e) {
         try {
           xhr = new ActiveXObject('Microsoft.XMLHTTP');
         } catch (e) {}
       }
    }
    if (xhr) {
       xhr.onreadystatechange = () =>{
           if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                 obj.success(xhr.responseText); //返回值傳callback
              } else {
                    //failcallback
                 obj.error('There was a problem with the request.');
              }
           } else {
              console.log('still not ready...');
           }
        };
       xhr.open(obj.method, obj.url, true);
       // 設(shè)置 Content-Type 為 application/x-www-form-urlencoded
       // 以表單的形式傳遞數(shù)據(jù)
       xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
       xhr.send(util(obj.data));//處理body數(shù)據(jù)
    }
    
    //處理數(shù)據(jù)
    const util = (obj)=>{
        var str = ''
        for (key in obj){
            str += key +'='+obj[key]+'&'

        }
        return str.substring(0,str.length-1)
    }
    
}

??ok,咱們已經(jīng)封裝完畢搔课,可以使用了胰柑,可是你會(huì)發(fā)現(xiàn),這種書寫方式很混亂爬泥,body柬讨,hearder亂七八糟,還有回掉地獄的問題袍啡。好的fetch出來(lái)了踩官。

fetch的出現(xiàn)

??我們說(shuō)了,一種東西的誕生有它的道理境输,他首先解決了回掉地獄的問題因?yàn)榉祷匾粋€(gè) promise 對(duì)象 蔗牡,對(duì) promise 對(duì)象不是很熟悉的同學(xué)可以看這篇文章: 你就需要這篇文章,帶你搞懂實(shí)戰(zhàn)的 Promise 對(duì)象嗅剖。同樣既然是 promise 對(duì)象我們就可以使用 es7 的 async / await 戳這里辩越。好了廢話不多說(shuō)我們看看最基礎(chǔ)的 fetch 怎么寫吧 。

fetch(url, options).then(function(response) {
  // handle HTTP response
}, function(error) {
  // handle network error
})

??就是這么方便信粮,就是這么簡(jiǎn)單黔攒。 fetch 會(huì)先發(fā)起一個(gè) option 的請(qǐng)求,確定是否連接成功,然后再發(fā)送正式的請(qǐng)求 亏钩,就好比 xhr.readyState === 4 這個(gè)一個(gè)道理莲绰。那有同學(xué)就問了欺旧,我的邏輯比較復(fù)雜 姑丑。我的 fetch 要加請(qǐng)求頭,參數(shù)我要傳參傳 formData 不是 json辞友。
我們來(lái)看fetch發(fā)送formdata:

fetch(url,{
    method:"post",
    headers:{
        "Content-type":"application:/x-www-form-urlencoded:charset=UTF-8"
    },
    body:"name=admin&password=123456"
}).then(function(response){
    if(response.ok){
        response.json().then(json => {
              console.log(json.result)
        })
    }
}).catch(function(err){
    console.log("Fetch錯(cuò)誤:"+err);
});

??發(fā)送json格式也非常簡(jiǎn)單栅哀。

fetch(url,{
    method:"post",
    headers:{
       'Content-Type':'application/json; charset=UTF-8'
    },
    body:JSON.stringify({name:'admin',password:123456})
}).then(function(response){
    if(response.ok){
        response.json().then(json => {
              console.log(json.result)
        })
    }
}).catch(function(err){
    console.log("Fetch錯(cuò)誤:"+err);
});

中止 取消 fetch

瀏覽器已經(jīng)開始為 AbortControllerAbortSignal 接口(也就是Abort API)添加實(shí)驗(yàn)性支持称龙,允許像 Fetch 和 XHR 這樣的操作在還未完成時(shí)被中止 。請(qǐng)參閱接口頁(yè)面了解更多詳情痴柔。但是目前對(duì)游覽器的支持并不很好疫向,所以我們其實(shí)可以換一種思路搔驼, 取消 fetch 我們可以從另外一個(gè)面入手 ---- 可以取消 promise 。原生的當(dāng)然不行了糯耍,所以我們這里用到了 bluebird温技。

例如多個(gè) fetch:


//傳統(tǒng) promise
var promises = [];
for (var i = 0; i < fileNames.length; ++i) {
    promises.push(fs.readFileAsync(fileNames[i]));
}
Promise.all(promises).then(function() {
    console.log("done");
});

// Using Promise.map:
import Promise from 'bluebird'
Promise.map(fileNames, function(fileName) {
    // Promise.map awaits for returned promises as well.
    return fs.readFileAsync(fileName);
}).then(function() {
    console.log("done");
});

終止取消多個(gè) fetch:

import Promise from 'bluebird'
Promise.map(fileNames, function(fileName) {
    // Promise.map awaits for returned promises as well.
    return fs.readFileAsync(fileName).then(()=>{
                //如果flag = true 就中斷荒揣。
                if (flag){
                  throw new Error('中斷')
                }
            });;
}).then(function() {
    console.log("done");
}).catch(function (err) {
    console.log('Error', err.message)
});

如果取消單個(gè) promise 可以用 .cancel 方法,具體看 bluebird 文檔翻具。

Axios 的出現(xiàn)

??從文檔中我們可以看出為什么這個(gè)會(huì)火 ,axios 他的功能非常強(qiáng)大,包括 取消請(qǐng)求 ,進(jìn)度處理等等挂据。但是我們看的是本質(zhì)還是 ajax ,在基礎(chǔ)上進(jìn)行了封裝和功能的添加

XMLHttpRequests
支持 Promise

//一個(gè)post請(qǐng)求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

結(jié)語(yǔ)

??其實(shí)我們看出來(lái)掷倔, ajax 和 Axios 在客戶端都是調(diào)用 XMLHttpRequests 對(duì)象 勒葱,而我們的 fetch 是一個(gè)新的游覽器對(duì)象 巴柿。只不過(guò) ajax 和 Axios 區(qū)別就是在 封裝了簡(jiǎn)便的方法广恢,并且提供了一個(gè) promise 對(duì)象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末至非,一起剝皮案震驚了整個(gè)濱河市睡蟋,隨后出現(xiàn)的幾起案子枷颊,更是在濱河造成了極大的恐慌夭苗,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傍菇,死亡現(xiàn)場(chǎng)離奇詭異丢习,居然都是意外死亡咐低,警方通過(guò)查閱死者的電腦和手機(jī)袜腥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)损痰,“玉大人酒来,你說(shuō)我怎么就攤上這事役首∠园荩” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵矮固,是天一觀的道長(zhǎng)档址。 經(jīng)常有香客問我邻梆,道長(zhǎng)浦妄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任蠢涝,我火速辦了婚禮和二,結(jié)果婚禮上耳胎,老公的妹妹穿的比我還像新娘。我一直安慰自己废登,他們只是感情好诗轻,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搔体,像睡著了一般半醉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缩多,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天梁钾,我揣著相機(jī)與錄音,去河邊找鬼姆泻。 笑死冒嫡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的方咆。 我是一名探鬼主播瓣赂,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼辜窑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了牙勘?” 一聲冷哼從身側(cè)響起方面,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤色徘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后横腿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揪惦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年器腋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钩杰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡措左,死狀恐怖媳荒,靈堂內(nèi)的尸體忽然破棺而出驹饺,到底是詐尸還是另有隱情缴渊,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布蝌借,位于F島的核電站菩佑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏稍坯。R本人自食惡果不足惜瞧哟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一枪向、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陨亡,春花似錦、人聲如沸聪舒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)止吁。三九已至,卻和暖如春盼理,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宏怔。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工臊诊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抓艳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓玷或,卻偏偏與公主長(zhǎng)得像偏友,于是被迫代替她去往敵國(guó)和親位他。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容