如何使用 fetch ,加請求頭, ajax 和 fetch 和 axios 的區別

----歡迎查看個人博客----javascript

什麼是fetch

  咱們以前,過分過來都在用ajax,那麼什麼是 Fetch ,Fetch 是新的遊覽器對象, 等同於 XMLHttpRequest對象 。它提供了許多與 XMLHttpRequest 相同的功能,但被設計成更具可擴展性和高效性。html

image

ajax

  廢話很少說咱們來看一下傳統的ajax。java

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);
    // 設置 Content-Type 爲 application/x-www-form-urlencoded
    // 以表單的形式傳遞數據
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('username=admin&password=root');
    
}

複製代碼

  好咱們來作層封裝,讓他變成咱們 jQuery 的 ajax post 如這種形式:ios

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

好的封裝開始:ajax

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);
	   // 設置 Content-Type 爲 application/x-www-form-urlencoded
	   // 以表單的形式傳遞數據
	   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	   xhr.send(util(obj.data));//處理body數據
	}
	
	//處理數據
	const util = (obj)=>{
		var str = ''
		for (key in obj){
			str += key +'='+obj[key]+'&'

		}
		return str.substring(0,str.length-1)
	}
	
}
複製代碼

  ok,我們已經封裝完畢,可使用了,但是你會發現,這種書寫方式很混亂,body,hearder亂七八糟,還有回掉地獄的問題。好的fetch出來了。json

fetch的出現

  咱們說了,一種東西的誕生有它的道理,他首先解決了回掉地獄的問題由於返回一個 promise 對象 ,對 promise 對象不是很熟悉的同窗能夠看這篇文章: 你就須要這篇文章,帶你搞懂實戰的 Promise 對象。一樣既然是 promise 對象咱們就可使用 es7 的 async / await 戳這裏。好了廢話很少說咱們看看最基礎的 fetch 怎麼寫吧 。axios

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

  就是這麼方便,就是這麼簡單。 fetch 會先發起一個 option 的請求,肯定是否鏈接成功,而後再發送正式的請求 ,就比如 xhr.readyState === 4 這個一個道理。那有同窗就問了,個人邏輯比較複雜 。個人 fetch 要加請求頭,參數我要傳參傳 formData 不是 json。 咱們來看fetch發送formdata:api

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錯誤:"+err);
});
複製代碼

  發送json格式也很是簡單。promise

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錯誤:"+err);
});
複製代碼

停止 取消 fetch

瀏覽器已經開始爲 AbortControllerAbortSignal 接口(也就是Abort API)添加實驗性支持,容許像 Fetch 和 XHR 這樣的操做在還未完成時被停止 。請參閱接口頁面瞭解更多詳情。可是目前對遊覽器的支持並不很好,因此咱們其實能夠換一種思路, 取消 fetch 咱們能夠從另一個面入手 ---- 能夠取消 promise 。原生的固然不行了,因此咱們這裏用到了 bluebird瀏覽器

例如多個 fetch:

//傳統 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");
});

複製代碼

終止取消多個 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)
});
複製代碼

若是取消單個 promise 能夠用 .cancel 方法,具體看 bluebird 文檔。

Axios 的出現

  從文檔中咱們能夠看出爲何這個會火 ,axios 他的功能很是強大,包括 取消請求 ,進度處理等等。可是咱們看的是本質仍是 ajax ,在基礎上進行了封裝和功能的添加

XMLHttpRequests 支持 Promise

//一個post請求

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

複製代碼

結語

  其實咱們看出來, ajax 和 Axios 在客戶端都是調用 XMLHttpRequests 對象 ,而咱們的 fetch 是一個新的遊覽器對象 。只不過 ajax 和 Axios 區別就是在 封裝了簡便的方法,而且提供了一個 promise 對象。

相關文章
相關標籤/搜索