Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

Vue Typescript下axios的封裝和使用

8 月到了,一個莫名其妙的機遇也砸到了臉上,提著行李一個人跑到了廣州跟一個畢業的師兄搞創業的項目,懷著點點的不安以及興奮,邁出離開學校的第一步。

由於就住在辦公室的一間房裡,出門即工作,開始了朝五晚九的工作生活,晚上的時候就折騰自己的項目,有點夢回星空時候夏訓營的感覺,很累也充實。每天也在掉頭髮以及煩惱吃什麼。

自己寫的華廣地圖給自家 eo 發了一份玩,結果給徵收了,上線成了星空的產品,並且要求再進行完善 😟
想了下乾脆給每個地點的 marker 添加一個點擊事件,點擊後可以看到該地點的詳細介紹,不過每個地方都要圖片,放在本地太大了,可能會造成卡頓,遂決定放在伺服器上,於是重新看了一遍 axios 同時自己學著網上的一些教程做了一個封裝,並解決了跨域的問題。

封裝 axios#

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'

const showStatus = (status: number) => {
  let message = ''
  switch (status) {
    case 400:
      message = '請求錯誤(400)'
      break
    case 401:
      message = '未授權,請重新登錄(401)'
      break
    case 403:
      message = '拒絕訪問(403)'
      break
    case 404:
      message = '請求出錯(404)'
      break
    case 408:
      message = '請求超時(408)'
      break
    case 500:
      message = '伺服器錯誤(500)'
      break
    case 501:
      message = '服務未實現(501)'
      break
    case 502:
      message = '網絡錯誤(502)'
      break
    case 503:
      message = '服務不可用(503)'
      break
    case 504:
      message = '網絡超時(504)'
      break
    case 505:
      message = 'HTTP版本不受支持(505)'
      break
    default:
      message = `連接出錯(${status})!`
  }
  return `${message}`
}

const service = axios.create({
  // 聯調
  baseURL: 'https://www.wanandroid.com',
  headers: {
    get: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
    },
    post: {
      'Content-Type': 'application/json;charset=utf-8'
    }
  },
  // 是否跨站點訪問控制請求
  withCredentials: true,
  timeout: 30000, //超時時間
  transformRequest: [(data) => {
    data = JSON.stringify(data)
    return data
  }],
  validateStatus () {
    // 使用async-await,處理reject情況較為繁瑣,所以全部返回resolve,在業務代碼中處理異常
    return true
  },
  transformResponse: [(data) => {
    if (typeof data === 'string' && data.startsWith('{')) {
      data = JSON.parse(data)
    }
    return data
  }]
})

// 請求攔截器
service.interceptors.request.use((config: AxiosRequestConfig) => {
    return config
}, (error) => {
    // 錯誤拋到業務代碼
    error.data = {}
    error.data.msg = '伺服器異常'
    return Promise.resolve(error)
})

// 響應攔截器
service.interceptors.response.use((response: AxiosResponse) => {
    const status = response.status
    let msg = ''
    if (status < 200 || status >= 300) {
        // 處理http錯誤,抛到業務代碼
        msg = showStatus(status)
        if (typeof response.data === 'string') {
            response.data = {msg}
        } else {
            response.data.msg = msg
        }
    }
    return response
}, (error) => {
    // 錯誤拋到業務代碼
    error.data = {}
    error.data.msg = '請求超時或伺服器異常'
    return Promise.resolve(error)
})

export default service

使用#

@Component
export default class Home extends Vue{
  a = []
  getSomeThings(){
    return request({
        url: "/wxarticle/list/408/1/json",
        method:'get'
    }).then((response)=>{
      this.a = response.data.data.datas
      console.log(this.a)
    }).catch((error)=>{
      console.log(error)
    })
  }

 mounted(){
   this.getSomeThings()
 }

解決跨域問題#

關於什麼是跨域之前在 ajax 上已經了解過了,是由瀏覽器的同源策略造成的,是瀏覽器對 js 施加的安全措施。

axios 解決跨域的思路#

我們可以配置一個代理的伺服器可以請求另一個伺服器中的數據,然後把請求出來的數據返回到我們的代理伺服器中,代理伺服器再返回數據給我們的客戶端,這樣我們就可以實現跨域訪問數據。

配置 proxy

在我們的 vue.config.js 下配置以下內容

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'https://www.wanandroid.com',// 你要請求的後端接口ip+port
                changeOrigin: true,// 允許跨域,在本地會創建一個虛擬服務端,然後發送請求的數據,並同時接收請求的數據,這樣服務端和服務端進行數據的交互就不會有跨域問題
                ws: true,// 開啟webSocket
                pathRewrite: {
                    '^/api': '',// 替換成target中的地址
                }
            }
        }
    }
}
配置 baseURL

在我們封裝的 axios 文件裡將 baseURL 更改為:’/api’

const service = axios.create({
  baseURL: '/api',

  …………

})

所以上面兩步操作是啥意思呢,其實就是:

我們請求 /wxarticle/list/408/1/json,就相當於請求了:localhost:8080/api/wxarticle/list/408/1/json,
然後配置的 proxy 攔截了 /api,並把 /api 以及前面的所有替換成了 target 的內容,
因此實際請求的 url 是https://www.wanandroid.com/wxarticle/list/408/1/json
即請求到了我們需要的接口了。

最後#

既然搞明白的差不多了,就上手吧,

學校的圖片呢?

啊?沒有啊

攝影那一邊呢? 😧

他們…… 也只有一部分…… 😧

啊…… 這…… 😩

綜上所述,項目目前搁淺中 💢

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。