標籤:跨域請求 cal 傳統 toc spi query bsp .data 網路
Fetch是什麼?
fetch是用來取代傳統的XMLHttpRequest的。 它的優點很多,包括鏈式調用的文法、返回promise等。
fetch api是基於promise的設計,它是為了取代傳統xhr的不合理的寫法而生的。
傳統的XMLHttpRequest請求閑的非常的雜亂,而優雅的ajax又不得不額外載入jQuery這個80K左右的架構
但是現在,我們可以使用Fetch,提供了對 Request 和 Response (以及其他與網路請求有關的)對象的通用定義,
它還提供了一種定 義,將 CORS 和 HTTP
原生的頭資訊結合起來,取代了原來那種分離的定義。
But,Fetch 相容性,可以看到,相容性很差,移動端全軍覆沒,不過可以使用Fetch polyfill
連結:https://www.jianshu.com/p/11f64a03d3f3 傳統的xhr請求寫起來非常的混亂,如:
1 var xhr = new XMLHttpRequest(); 2 xhr.open(‘GET‘, url); 3 xhr.responseType = ‘json‘; 4 5 xhr.onload = function() { 6 console.log(xhr.response); 7 }; 8 9 xhr.onerror = function() {10 console.log("Oops, error");11 };12 13 xhr.send();
但是使用fetch之後,如:
1 fetch(url).then(function(response) {2 return response.json();3 }).then(function(data) {4 console.log(data);5 }).catch(function(e) {6 console.log("Oops, error");7 });
所以是這種鏈式調用的風格看上去會非常舒服。
如果我們再使用了箭頭函數就會更加簡潔了。
1 fetch(url).then(response => response.json())2 .then(data => console.log(data))3 .catch(e => console.log("Oops, error", e))基本使用方法
fetch必須接受一個資源路徑作為參數,並且返回了一個promise,所以我們可以直接使用鏈式調用的方式。
1 fetch("/getAllProduct").then(function(res) { 2 return res.json(); 3 }).then(function (data) { 4 if (data.code == 200) { 5 console.log(‘擷取到所有產品‘ ,data.data); 6 that.props.addAllProduct(data.data); 7 } else { 8 console.log(data.message); 9 }10 })
這樣,我們就可以發送一個ajax請求。
1 /* 對用戶端的返回資料封裝 2 * @param [code] (number) code為返回的狀態代碼 3 * @param [message] (string) message為返回的資訊 4 * @param [data] (any) data是可選的,為返回給前端的資料 5 */ 6 // 注意: retrunJson中的res為node處理介面的回呼函數中的res,這個是必須的。 7 function returnJson(res, code, message, data) { 8 var response = { 9 code: code, 10 message: message 11 }; 12 if (typeof data !== ‘undefined‘) { 13 response.data = data; 14 } 15 res.json(response); 16 // 返回這個請求之後,必須要 res.end()表示請求的結束,否則後台可能會崩潰。 17 res.end(); 18 } 19 20 router.post(‘/register‘, function (req, res) { 21 let userName = req.body.username, 22 password = req.body.password, 23 passwordAgain = req.body.passwordAgain, 24 type = req.body.type; 25 console.log(userName, password, type); 26 if (type == 1) { 27 if (password == passwordAgain) { 28 let managerId = uuidv1(); 29 30 console.log(userName, password, passwordAgain); 31 32 var newUser = new Manager({ 33 name: userName, 34 password: password, 35 type: req.body.type, 36 managerId: managerId 37 }); 38 39 Manager.find(userName, function (err, user) { 40 if (err) { 41 returnJson(res, 5001, ‘伺服器錯誤,註冊失敗‘); 42 } else { 43 if (user !== null) { 44 returnJson(res, 4003, "此使用者已經註冊!"); 45 } else { 46 // 如果符合條件,就註冊該使用者,將資料儲存在資料庫。 47 newUser.save(function (err, user) { 48 if (err) { 49 // 伺服器端錯誤,失敗返回狀態代碼500 50 returnJson(res, 500, "使用者註冊失敗!"); 51 } else { 52 // user資料較簡單,直接傳遞user即可,如果複雜,我們可以考慮使用對象形式傳遞更多資料。 53 returnJson(res, 200, "使用者註冊成功!", user); 54 } 55 }); 56 } 57 } 58 }); 59 } else { 60 returnJson(res, 4001, "使用者兩次輸入密碼不一致!"); 61 } 62 } else if( type == 2) { 63 64 if (password == passwordAgain) { 65 let userId = uuidv1(); 66 67 console.log(userName, password, passwordAgain); 68 69 var newUser = new User({ 70 name: userName, 71 password: password, 72 type: req.body.type, 73 userId: userId 74 }); 75 76 User.find(userName, function (err, user) { 77 if (err) { 78 returnJson(res, 5001, ‘伺服器錯誤,註冊失敗‘); 79 } else { 80 if (user !== null) { 81 returnJson(res, 4003, "此使用者已經註冊!"); 82 } else { 83 // 如果符合條件,就註冊該使用者,將資料儲存在資料庫。 84 newUser.save(function (err, user) { 85 if (err) { 86 // 伺服器端錯誤,失敗返回狀態代碼500 87 returnJson(res, 500, "使用者註冊失敗!"); 88 } else { 89 // user資料較簡單,直接傳遞user即可,如果複雜,我們可以考慮使用對象形式傳遞更多資料。 90 returnJson(res, 200, "使用者註冊成功!", user); 91 } 92 }); 93 } 94 } 95 }); 96 } else { 97 returnJson(res, 4001, "使用者兩次輸入密碼不一致!"); 98 } 99 }100 });
這樣,我們就可以處理一個ajax請求。
注意點:
1、fetch() 返回的是一個Promise對象。
fetch使用的promise對象可以使得我們使用同步的方式寫非同步函數。
2、 fetch api是可以結合 async 和 await 來使用的。
fetch是基於promise實現的,但是使用promise的寫法,我們還是可以看到callback的影子,如果結合 async和await來使用,還是非常不錯的。
3、 Fetch api 提供的spi囊括但是不限於xhr的所有功能。
4、 fetch api 可以跨域。
參考: https://fetch.spec.whatwg.org/#http-cors-protocol
跨域請求必須包括 Origin 作為header.
5、fetch提供了對request和response對象的通用定義。
Fetch 提供了對 Request 和 Response (以及其他與網路請求有關的)對象的通用定義。所以在一個Fetch請求中,完全可以只使用Request 和 Response兩個對象,通過Request 設定參數,通過Response 對傳回值進行處理。
所以,我們可以將一個fetch定義如下:
1 var myHeaders = new Headers(); 2 myHeaders.append(‘Content-Type‘, ‘image/jpeg‘); 3 var option = { method: ‘GET‘, 4 headers: myHeaders, 5 mode: ‘cors‘, 6 cache: ‘default‘ }; 7 var myRequest = new Request(‘https://api.github.com/users/mzabriskie‘,option); 8 fetch(myRequest).then(function(response) { 9 ... 10 });
參考文章: https://github.com/camsong/blog/issues/2
FetchAPI 的使用