fetch请求用法以及封装

一、说明

原生js提供了两种数据请求方式fetch,ajax

- ajax需要封装的, fetch不需要

- ajax不太符合MV* 开发方式,fetch可以认为是js为了MV*方式做的量身打造

- fetch也是Promise

 

功能:用fetch请求动态数据

1、get请求

(1)不带参数

  // 通过fetch获取百度的错误提示页面
   fetch('https://www.baidu.com/search/error.html') // 返回一个Promise对象
     .then((res)=>{
       return res.text() // res.text()是一个Promise对象
     })
     .then((res)=>{
       console.log(res) // res是最终的结果
     })

(2)带参数:

get请求参数是连接在url上

 methods: {
         get () {
           fetch(`${ BASE_URL }/get.php?a=1&b=2`)//get请求参数是连接在url上
             .then( data => data.text() )
             .then( res => {
               this.num = res
             })
             .catch( err => console.log( err ))
         },

method: 'GET'不写默认是get请求

 

2、post请求

(1)不带参数

   // 通过fetch获取百度的错误提示页面
   fetch('https://www.baidu.com/search/error.html', {
       method: 'POST' // 指定是POST请求
     })
     .then((res)=>{
       return res.text()
     })
     .then((res)=>{
       console.log(res)
    })

(2)带参数

post请求传递参数:

body: new URLSearchParams([["a", 1],["b", 2]]).toString()

注意:POST请求的参数,一定不能放在URL中,这样做的目的是防止信息泄露。

    post () {
           /*
             1. post请求参数如何携带
           */
           fetch(`${ BASE_URL }/post.php`,{
             method: 'POST',
             // body: JSON.stringify({
             //   a: 1,
             //   b: 2
            // })
            headers: new Headers({
              'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
            }),
            body: new URLSearchParams([["a", 1],["b", 2]]).toString()
          }).then( data => data.text() )
            .then( res => {
              this.sum = res
            })
            .catch( err => console.log( err ))
        },

 

总结:

fetch( url, config ).then().then().catch()

    getMovies () {
           /* 第一个then是为数据格式化,可以格式化的数据类型有: json  text   blob[ 二进制 ]
              第二个then才是得到的数据
           */
           // fetch( url, config ).then().then().catch()
   
           fetch('./mock/movie.json')
             .then( data => data.json() )
             .then( res => {
              console.log("兵哥: getMovies -> res", res)
              this.movies = res.movieList
            })
        }

 

得到json格式数据:

   // 通过fetch获取百度的错误提示页面
   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中写上传递的参数
       method: 'GET',
       headers: new Headers({
         'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON
       })
     })
     .then((res)=>{
       return res.json() // 返回一个Promise,可以解析成JSON
    })
    .then((res)=>{
      console.log(res) // 获取JSON数据
    })

 

格式化数据:

data.json()

data.text()

处理数据可以使用querystring

   const qs = require( 'querystring' )
   const str = 'a=1&b=2'
   const obj = { a: '1', b: '2' }
   console.log( qs.parse( str ))
   console.log( qs.stringify( obj ))

 

强制带Cookie:

   // 通过fetch获取百度的错误提示页面
   fetch('https://www.baidu.com/search/error.html', {
       method: 'GET',
       credentials: 'include' // 强制加入凭据头
     })
     .then((res)=>{
       return res.text()
     })
     .then((res)=>{
      console.log(res)
    })

 

二、fetch的封装

 

   /**
    * 将对象转成 a=1&b=2的形式
    * @param obj 对象
    */
   function obj2String(obj, arr = [], idx = 0) {
     for (let item in obj) {
       arr[idx++] = [item, obj[item]]
     }
     return new URLSearchParams(arr).toString()
  }
  
  /**
   * 真正的请求
   * @param url 请求地址
   * @param options 请求参数
   * @param method 请求方式
   */
  function commonFetcdh(url, options, method = 'GET') {
    const searchStr = obj2String(options)
    let initObj = {}
    if (method === 'GET') { // 如果是GET请求,拼接url
      url += '?' + searchStr
      initObj = {
        method: method,
        credentials: 'include'
      }
    } else {
      initObj = {
        method: method,
        credentials: 'include',
        headers: new Headers({
          'Accept': 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded'
        }),
        body: searchStr
      }
    }
    fetch(url, initObj).then((res) => {
      return res.json()
    }).then((res) => {
      return res
    })
  }
  
  /**
   * GET请求
   * @param url 请求地址
   * @param options 请求参数
   */
  function GET(url, options) {
    return commonFetcdh(url, options, 'GET')
  }
  
  /**
   * POST请求
   * @param url 请求地址
   * @param options 请求参数
   */
  function POST(url, options) {
    return commonFetcdh(url, options, 'POST')
  }
  GET('https://www.baidu.com/search/error.html', {a:1,b:2})
  POST('https://www.baidu.com/search/error.html', {a:1,b:2})