切换语言为:繁体

axios封装http方法

  • 爱糖宝
  • 2024-09-30
  • 2064
  • 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.