切換語言為:簡體

axios封裝http方法

  • 爱糖宝
  • 2024-09-30
  • 2070
  • 0
  • 0

一、建立http例項

const http = axios.create({
  // 請求超時時間設定為 30 秒,超過這個時間請求會被終止
  timeout: 1000 * 30,
  // 允許跨域請求時攜帶憑證(如 Cookies)
  withCredentials: true,
  // 設定請求頭的 Content-Type 為 application/json; charset=utf-8,表明請求體的格式是 JSON,並指定字元編碼。
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
})

headers: { 'Content-Type': 'application/json; charset=utf-8' }
設定了請求的內容型別,表明傳送的資料格式為 JSON。這對於伺服器理解請求體中的資料格式至關重要。
透過指定 charset=utf-8,你還確保了字元編碼正確,尤其是在處理非ASCII字元時。這可以避免因編碼不匹配導致的資料解析錯誤。

如果沒有加上 Content-Type: application/json; charset=utf-8,伺服器可能無法正確解析請求體中的資料。具體後果包括:

  1. 資料解析錯誤:伺服器可能會將請求體當作預設的表單數據處理,從而導致資料無法被正確解析。

  2. 請求失敗:一些 API 可能要求明確的 Content-Type,如果未提供,可能返回錯誤響應,例如 400 Bad Request。

  3. 字元編碼問題:如果請求體包含非 ASCII 字元,伺服器可能會使用預設的字元編碼(通常是 ISO-8859-1),從而導致亂碼或解析錯誤。

總之,明確設定 Content-Type 有助於確保資料在傳輸過程中的一致性和正確性。

二、配置請求攔截器

http.interceptors.request.use(config => {
  config.headers['token'] = Vue.cookie.get('token') // 請求頭帶上token
  return config
}, error => {
  return Promise.reject(error)
})

三、配置響應攔截器

http.interceptors.response.use(response => {
  if (response.data && response.data.code === 401) { // 401, token失效
    clearLoginInfo()
    router.push({ name: 'login' })
  }
  console.log('response',response); // 在這裏檢視響應資訊
  return response
}, error => {
  return Promise.reject(error)
})

console.log('response',response)的結果

axios封裝http方法

axios封裝http方法

四、請求地址處理

http.adornUrl = (actionName) => {
  // 非生產環境 && 開啟代理, 介面字首統一使用[/proxyApi/]字首做代理攔截!
  return (process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY ? '/proxyApi/' : window.SITE_CONFIG.baseUrl) + actionName
}

五、GET請求引數處理

/**
 * get請求引數處理
 * @param {*} params 引數物件
 * @param {*} openDefultParams 是否開啟預設引數?
 */
http.adornParams = (params = {}, openDefultParams = true) => {
  var defaults = {
    't': new Date().getTime()
  }
  return openDefultParams ? merge(defaults, params) : params
}

新增時間戳 't': new Date().getTime()的好處:

  1. 確保請求的唯一性,避免瀏覽器或伺服器端的快取影響

  2. 用於請求的跟蹤和日誌記錄。伺服器可以記錄每次請求的時間戳,這對於分析請求頻率、響應時間等效能指標非常有用

  3. 在一定程度上增加表單重複提交的難度

  4. 將時間戳等預設引數封裝在函式內部,減少了程式碼冗餘

六、POST請求引數處理

http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => {
  var defaults = {
    't': new Date().getTime()
  }
  data = openDefultdata ? merge(defaults, data) : data
  return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
}

函式根據 contentType 引數的值來決定如何格式化合並後的資料。如果 contentType 為 'json'(預設值),則使用 JSON.stringify 方法將物件轉換為JSON格式的字串。如果 contentType 不是 'json',則假設是表單資料(application/x-www-form-urlencoded 或 multipart/form-data),並使用 qs.stringify 方法(這裏假設 qs 是一個查詢字串(query string)解析和字串化庫,如qs npm包)將物件轉換為查詢字串格式的字串。

七、將http例項掛載全域性

在vue專案的main.js中

import httpRequest from '@/utils/httpRequest'
Vue.prototype.$http = httpRequest

八、使用get方法

    async getMarketList() {
      this.$http({
        url: this.$http.adornUrl('/xxx/xxx/xxxxxxxxx'),
        method: 'get'
      }).then(({
        data
      }) => {
        if (data && data.code === 0) {
          this.marketList = data.data
          //   console.log('this.marketList', this.marketList)
        } else {
          this.marketList = []
        }
      })
    },

九、使用post方法

// 提交表單
        dataFormSubmit() {
            // console.log(Encrypt(this.dataForm.password));
            this.$refs['dataForm'].validate((valid) => {
                if (valid) {
                    this.$http({
                        url: this.$http.adornUrl('/xxxx/login'),
                        method: 'post',
                        data: this.$http.adornData({
                            'username': this.dataForm.userName,
                            'password': Encrypt(this.dataForm.password),
                            'uuid': this.dataForm.uuid,
                            'captcha': this.dataForm.captcha
                        })
                    }).then(({ data }) => {
                        if (data && data.code === 0) {
                            this.$cookie.set('token', data.token)
                            this.$router.replace({ name: 'home' })
                        } else {
                            this.getCaptcha()
                            this.$message.error(data.msg)
                        }
                    })
                }
            })
        },

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.