一、說明
原生js提供了兩種數據請求方式fetch,ajax
- ajax需要封裝的, fetch不需要
- ajax不太符合MV* 開發方式,fetch可以認為是js為了MV*方式做的量身打造
- fetch也是Promise
功能:用fetch請求動態數據
1、get請求
(1)不帶參數
1 // 通過fetch獲取百度的錯誤提示頁面 2 fetch('https://www.baidu.com/search/error.html') // 返回一個Promise對象 3 .then((res)=>{ 4 return res.text() // res.text()是一個Promise對象 5 }) 6 .then((res)=>{ 7 console.log(res) // res是最終的結果 8 })
(2)帶參數:
get請求參數是連接在url上
1 methods: { 2 get () { 3 fetch(`${ BASE_URL }/get.php?a=1&b=2`)//get請求參數是連接在url上 4 .then( data => data.text() ) 5 .then( res => { 6 this.num = res 7 }) 8 .catch( err => console.log( err )) 9 },
method: 'GET'不寫默認是get請求
2、post請求
(1)不帶參數
1 // 通過fetch獲取百度的錯誤提示頁面 2 fetch('https://www.baidu.com/search/error.html', { 3 method: 'POST' // 指定是POST請求 4 }) 5 .then((res)=>{ 6 return res.text() 7 }) 8 .then((res)=>{ 9 console.log(res) 10 })
(2)帶參數
post請求傳遞參數:
body: new URLSearchParams([["a", 1],["b", 2]]).toString()
注意:POST請求的參數,一定不能放在URL中,這樣做的目的是防止信息泄露。
1 post () { 2 /* 3 1. post請求參數如何攜帶 4 */ 5 fetch(`${ BASE_URL }/post.php`,{ 6 method: 'POST', 7 // body: JSON.stringify({ 8 // a: 1, 9 // b: 2 10 // }) 11 headers: new Headers({ 12 'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式為表單提交 13 }), 14 body: new URLSearchParams([["a", 1],["b", 2]]).toString() 15 }).then( data => data.text() ) 16 .then( res => { 17 this.sum = res 18 }) 19 .catch( err => console.log( err )) 20 },
總結:
fetch( url, config ).then().then().catch()
1 getMovies () { 2 /* 第一個then是為數據格式化,可以格式化的數據類型有: json text blob[ 二進制 ] 3 第二個then才是得到的數據 4 */ 5 // fetch( url, config ).then().then().catch() 6 7 fetch('./mock/movie.json') 8 .then( data => data.json() ) 9 .then( res => { 10 console.log("兵哥: getMovies -> res", res) 11 this.movies = res.movieList 12 }) 13 }
得到json格式數據:
1 // 通過fetch獲取百度的錯誤提示頁面 2 fetch('https://www.baidu.com/rec?platform=wise&ms=1&rset=rcmd&word=123&qid=11327900426705455986&rq=123&from=844b&baiduid=A1D0B88941B30028C375C79CE5AC2E5E%3AFG%3D1&tn=&clientWidth=375&t=1506826017369&r=8255', { // 在URL中寫上傳遞的參數 3 method: 'GET', 4 headers: new Headers({ 5 'Accept': 'application/json' // 通過頭指定,獲取的數據類型是JSON 6 }) 7 }) 8 .then((res)=>{ 9 return res.json() // 返回一個Promise,可以解析成JSON 10 }) 11 .then((res)=>{ 12 console.log(res) // 獲取JSON數據 13 })
格式化數據:
data.json()
data.text()
處理數據可以使用querystring
1 const qs = require( 'querystring' ) 2 const str = 'a=1&b=2' 3 const obj = { a: '1', b: '2' } 4 console.log( qs.parse( str )) 5 console.log( qs.stringify( obj ))
強制帶Cookie:
1 // 通過fetch獲取百度的錯誤提示頁面 2 fetch('https://www.baidu.com/search/error.html', { 3 method: 'GET', 4 credentials: 'include' // 強制加入憑據頭 5 }) 6 .then((res)=>{ 7 return res.text() 8 }) 9 .then((res)=>{ 10 console.log(res) 11 })
二、fetch的封裝
1 /** 2 * 將對象轉成 a=1&b=2的形式 3 * @param obj 對象 4 */ 5 function obj2String(obj, arr = [], idx = 0) { 6 for (let item in obj) { 7 arr[idx++] = [item, obj[item]] 8 } 9 return new URLSearchParams(arr).toString() 10 } 11 12 /** 13 * 真正的請求 14 * @param url 請求地址 15 * @param options 請求參數 16 * @param method 請求方式 17 */ 18 function commonFetcdh(url, options, method = 'GET') { 19 const searchStr = obj2String(options) 20 let initObj = {} 21 if (method === 'GET') { // 如果是GET請求,拼接url 22 url += '?' + searchStr 23 initObj = { 24 method: method, 25 credentials: 'include' 26 } 27 } else { 28 initObj = { 29 method: method, 30 credentials: 'include', 31 headers: new Headers({ 32 'Accept': 'application/json', 33 'Content-Type': 'application/x-www-form-urlencoded' 34 }), 35 body: searchStr 36 } 37 } 38 fetch(url, initObj).then((res) => { 39 return res.json() 40 }).then((res) => { 41 return res 42 }) 43 } 44 45 /** 46 * GET請求 47 * @param url 請求地址 48 * @param options 請求參數 49 */ 50 function GET(url, options) { 51 return commonFetcdh(url, options, 'GET') 52 } 53 54 /** 55 * POST請求 56 * @param url 請求地址 57 * @param options 請求參數 58 */ 59 function POST(url, options) { 60 return commonFetcdh(url, options, 'POST') 61 } 62 GET('https://www.baidu.com/search/error.html', {a:1,b:2}) 63 POST('https://www.baidu.com/search/error.html', {a:1,b:2})