1. 程式人生 > 實用技巧 >fetch請求用法以及封裝

fetch請求用法以及封裝

一、說明

原生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})