網絡模塊封裝

網絡模塊封裝

1、選擇什麼網絡模塊

選擇一 :傳統的 Ajax 是基於 XMLHttpRequest(XHR)
  • 爲何不用它呢?
    • 很是好解釋,配置和調用方式很是混亂。
    • 編碼起來看起來就很是蛋疼。
    • 因此真是開發中不多直接使用,而是使用 jQuery—Ajax
選擇二 :JQuery-Ajax
  • 相對於傳統的 Ajax 很是好用
  • 爲何不用?
    • 首先,咱們先明確一點: 在 Vue 的整個開發中都是不須要使用 jQuery了。
    • 那麼,就意味着爲了方便咱們進行一個網絡請求,特地應用一個jQuery,就不合理了。
    • jQuery 的代碼 1w+ 行。
    • Vue的代碼才 1w+ 行。
    • 徹底不必爲了用網絡請求就應用這個重量級的框架。
選擇三 :官方在Vue1.x 的時候,推出來 Vue-resource.
  • 優勢
    • Vue-resource 的體積相對於 jQuery 小不少
    • 另外 Vue-resource是官方推出來的。
  • 爲何不用?
    • 在 Vue2.0 推出後, Vue 做者就在 GitHub 的 Issues 中說明了去掉 vue-resource, 而且之後也不會再更新。
    • 對之後的項目開發和維護都存在很大的隱患
選擇四 :在說明不在繼續更新和維護 vue-resource 的同時,做者還推薦了一個框架: axios
  • 爲何用它?
    • axios 有很是多的優勢 ,而且用起來也很是的方便。

2、jsonp

  • 在前端開發中,咱們一種常見的網絡請求方式就是 JSONPjavascript

  • 使用 JSONP 最主要的緣由是爲了解決跨域訪問的問題。前端

  • JSONP 的原理是什麼呢?vue

    • JSONP 的核心在於經過 script 標籤的 src 來幫助咱們請求數據。
    • 緣由是咱們的項目部署在domain1.com 服務器上時,是不能直接訪問 domain2.com 服務器上的資料的。
    • 這個時候,咱們利用 script 標籤的src 來幫助咱們去服務器 請求 到數據,將數據當作一個 JavaScript的函數䣂執行,而且執行的過程當中傳入咱們須要的 json。
    • 全部,封裝 jsonp 的核心就在於咱們 監聽 window上的 jsonp 進行回調的名稱。
  • JSONP 如何封裝呢?java

    • 咱們一塊兒本身來封裝一個出來 JSONP的代碼吧。node

      let count = 1
      export default function originPJSONP(option) {
          // 1. 從傳入的 option 中提取 URL
          const url = option.url;
      
          // 2. 在body中添加 script 標籤
          const body = document.getElementsByTagName('body')[0];
          const script = document.createElement('script');
      
          // 3. 內部生成一個 不重複的 callback
          const callback = 'jsonp' + count++;
      
          // 4. 監聽 window 上的 jsonp 的調用
          return new Promise((resolve, roject) => {
              try {
                  window[callback] = function (result) {
                      body.removeChild(script);
                      resolve(result)
                  }
                  const params = handleParam(option.data);
                  body.appendChild(script)
              } catch (e) {
                  body.removeChild(script)
                  reject(e)
              }
          })
      }
      function handleParam(data) {
          let url = ''
          for (let key in data) {
              let value = data[key] !== undefined ? data[key] : ''
              url += `&${key} = ${encodeURIComponent(value)}` 
          }
          return url
      }

3、爲何選擇 axios

一、功能特色:
  • 在瀏覽器中發送 XMLHttpRequests 請求
  • 在 node.js 中發送 http 請求
  • 支持 Promise API
  • 攔截請求和 響應
  • 轉換 請求 和 響應數據
  • 等等
二、補充 : axios 名稱的由來、我的理解

axios : Ajax i/o systemjquery

三、axios 請求方式
  • 支持多種請求方式ios

    • axios(config)
    • axios.request(config)
    • axios.get(url[, config])
    • axios.delete(url[, config])
    • axios.head(url[, config])
    • axios.post(url[, data[, config]])
    • axios.put(url[, data[, config]])
    • axios.patch(url[, data[, config]])
  • 如何發送請求呢?ajax

    • 案例:發送 get 請求json

      import axios from 'axios'
      
      export default {
          name: 'app',
          created() {
              // 提問: 爲何沒有跨域問題
              // 1. 沒有請求參數
              axios.get("http://www.liulongbin.top:3005/api/getlunbo")
              .then(res => {
                  console.log(res);
              }).catch(err => {
                  console.log(err);
              })
      
              // 2. 有請求參數
              axios.get('http://123.207.32.32:8000/home/data', {params: { type: 'sell', page: 1}})
              .then(res => {
                  console.log(res);
              }).catch(err => {
                  console.log(err);
              })
          }
      }
  • 發送併發請求axios

    • 有時候,咱們能夠須要同時發送兩個請求

      • 使用 axios.all , 能夠放入多個請求的數組,

      • axios.all([]) 返回的結果是一個數組,使用 axios.spread 可將數組 [res1,res2] 展開爲 res1, res2

        // 2. axios 發送併發請求
        axios
          .all([
            axios({
              url: "http://www.liulongbin.top:3005/api/getlunbo"
            }),
            axios({
              url: "http://123.207.32.32:8000/home/data",
              params: {
                type: "sell",
                page: 3
              }
            })
          ])
          .then(res => {
            axios.spread((res1, res2) => {
              console.log(res1);
              console.log(res2);
            });
          });
  • 全局配置

    • 在上面的實例中,咱們的 BaseURL 是固定的

      • 事實上,在併發中肯不少參數都是固定的

      • 這個時候咱們能夠進行一些抽取,也能夠利用axios的全局配置

        axios.defaults.baseURL = 'http://www.liulongbin.top:3005/api'
        axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlenconded';
        // 提取全局配置
        axios.defaults.baseURL = "http://www.liulongbin.top:3005/api"
        
        axios
          .all([
            axios({
              url: "/getlunbo"
            }),
            axios({
              // url: "http://123.207.32.32:8000/home/data",
              url: "/getnewslist",
            })
          ])
          .then(res => {
            axios.spread((res1, res2) => {
              console.log(res1);
              console.log(res2);
            });
          });
四、常見的配置選項
  • 請求地址
    • url: '/user',
  • 請求類型
    • method: 'get',
  • 請求根路徑
  • 請求前的數據處理
    • transformRequest: [function(data) {}],
  • 自定義的請求頭
    • headers: {'x-Requested-With':'XMLHttpRequest'},
  • URL查詢對象
    • params:{id: 12},
五、axios 的實例
  • 爲何要建立 axios 的實例呢

    • 當咱們從 axios 模塊中導入對象時,使用的實例是默認的實例

    • 當給該實例設置一些默認配置時,這些配置就被固定下來了。

    • 可是後續開發中,某些配置可能會不太同樣

    • 好比某些請求須要使用特定的 baseURL 或者 timeout 或者 content-Type 等

    • 這個時候,咱們就能夠建立新的實例,而且傳入屬於該實例的配置信息

      // 建立新的實例
      const axiosInstance = axios.create({
          baseURL: 'http://123.207.32.32:8000',
          timeout: 5000,
          headers: {}
      })
```json
    // 發送網絡請求
axiosInstance({
        url: '/category',
        method: 'get'
    }).then(res => {
        console.log(res)
    }).catch(err) => {
        console.log(err)
    }

六、axios 封裝 (使用 Promise 進行封裝)
import originAxios from 'axios'

export default function axios(option) {
    return new Promise((reslove, reject) => {
        // 1. 建立 axios 的實例
        const instance =originAxios.create({
            baseURL: 'api',
            timeout: 5000
        })
        
        // 2. 傳入對象進行網絡請求
        instance(option).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}
七、如何使用攔截器
  • axios 提供了攔截器,用於咱們在發送每次請求或者獲得響應後,進行對應的處理。

  • 如何使用攔截

    // 配置請求和響應攔截
    instance.interceptors.request.use(config => {
        // 請求攔截成功
        console.log('來到了 request 攔截 success中')
        return config
    }, err => {
        // 請求攔截失敗
        console.log('request 攔截 failure 中')
    })
    
    instance.interceptors.response.use(response => {
        // 響應攔截成功
        console.log('來到了 response 攔截 success 中')
        return response.data
    }, err => {
        // 響應攔截失敗
        console.log('來到了 response 攔截 failure 中')
        return err
    })
相關文章
相關標籤/搜索