所有文章 > API设计 > axios中restful api的使用

axios中restful api的使用

1引子

在前端发送网络请求的时候,现在最经常使用的是axios, 而axios的api中我们(确切说是我)最常用的就是post,而其他api很少有用到的场景。最近在做一个简单需求(增删改查)的时候,后端给的接口是restful风格的。看看吧:

嗯,看到上图我还没感觉到什么,接着看:

嗯?看到这些的时候我慌张了。。。还好,不就是restful风格的吗?我修改封装axios的代码去~

2 封装axios方法

先看看原来封装的get代码:

function get(requestData) {
  return new Promise((resolve, reject) => {
    processLoading(requestData.loading);
    axios({
      method: "get",
      timeout: requestData.timeout !== undefined ? requestData.timeout : 10000,
      url: processURL(requestData.service, requestData.url, requestData.urlItem, requestData.transURL),
      params: requestData.token ? processToken(common.deepCopy(requestData.data)) : requestData.data,
      headers: requestData.headers || {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    })
      .then(response => {
        resolve(response.data);
      })
      .catch((error) => {
        loadingClose();
        // Global.messageErr("网络异常");
        // reject(error);
      });
  })
}

再看看原来封装的post方法:

/**
 * 封装axios的post请求
 * @param {*} requestData
 */
function post(requestData) {
  return new Promise((resolve, reject) => {
    processLoading(requestData.loading);
    axios({
      method: "post",
      timeout: requestData.timeout !== undefined ? requestData.timeout : 10000,
      url: processURL(requestData.service, requestData.url, requestData.urlItem, requestData.transURL),
      data: requestData.token ? processToken(common.deepCopy(requestData.data)) : requestData.data,
      headers: requestData.headers || {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    })
      .then(response => {
        resolve(response.data);
      })
      .catch((error) => {
        loadingClose();
        // Global.messageErr("网络异常");
        // reject(error);
      });
  })
}

注意get方法和post方法在传数据时候的区别,数据参数对应的键名分别是params和data。可以看看axios文档中两个方法的方法签名:

axios#get(url[, config])
axios#post(url[, data[, config]])

在文档中也介绍了config对象中可以配置params或者data, 二者的区别是:params是即将与请求一起发送的 URL 参数,data是作为请求主体被发送的数据,只适用于这些请求方法 ‘PUT’, ‘POST’, 和 ‘PATCH’。有这两个方法我很快就能照葫芦画瓢,写put方法,delete方法:

/**
 * 封装axios的put请求
 * @param {*} requestData
 */
 function put(requestData) {
  return new Promise((resolve, reject) => {
    processLoading(requestData.loading);
    axios({
      method: "put",
      timeout: requestData.timeout !== undefined ? requestData.timeout : 10000,
      url: processURL(requestData.service, requestData.url, requestData.urlItem, requestData.transURL),
      data: requestData.token ? processToken(common.deepCopy(requestData.data)) : requestData.data,
      headers: requestData.headers || {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    })
      .then(response => {
        resolve(response.data);
      })
      .catch((error) => {
        loadingClose();
        // Global.messageErr("网络异常");
        // reject(error);
      });
  })
}

put方法没有什么特别的,method设置为put即可。

 function remove(requestData) {
  return new Promise((resolve, reject) => {
    processLoading(requestData.loading);
    axios({
      method: "delete",
      timeout: requestData.timeout !== undefined ? requestData.timeout : 10000,
      url: processURL(requestData.service, requestData.url, requestData.urlItem, requestData.transURL),
      params: requestData.token ? processToken(common.deepCopy(requestData.data)) : requestData.data,
      headers: requestData.headers || {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    })
      .then(response => {
        resolve(response.data);
      })
      .catch((error) => {
        loadingClose();
        // Global.messageErr("网络异常");
        // reject(error);
      });
  })
}

注意delete是js的关键字(保留字)所以不能用作方法名,这里用remove表示删除。如此一来就可以调用接口啦~下面记录几个需要注意的问题:

3 注意的问题

1.put方法和delete方法的url处理

后端给的put方法和delete方法的接口路径都是:

/recommend/localspot/{id}

其中的id要在调用接口的时候动态拼上数据的id, 所以url要变成传参的形式:

/**
 *编辑数据推荐
 */
 export const localspotUpdate = params => api.put({
  service: 'TRAVEL_DATA_APP_URL_PUT',
  url: params.url,
  headers: {
    'Content-Type': 'application/json; charset=UTF-8'
  },
  urlItem: '1/',
  data: params.data,
  loading: true
})


/**
 *删除数据推荐
 */
 export const localspotDelete = params => api.delete({
  service: 'TRAVEL_DATA_APP_URL_DELETE',
  url: params.url,
  urlItem: '',
  data: params.data,
  loading: true
})

页面当中是如何调用的呢?代码如下:

deleteFun(row) {
  const that = this
  this.$confirm("确定要删除这条记录吗", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    localspotDelete({url: `/recommend/localspot/${row.spotId}`, data: {}}).then(res=>{
      console.log(res)
      if(res.respCode == this.ConstUtils.NUMBER_100){
        // 删除成功刷新列表
        that.$refs.mxTable.reload(null, "delete")
      } else {
        that.$message.error(that.errorCodeMap[res.respCode] || '系统错误,请联系管理员');
      }
    })
  });
}

注意代码中调用localspotDelete方法时,参数url中拼接的spotId。 

2.注意几个不常用的http状态码 

我在调试的时候遇到了如下几个:405 请求方式不正确 201 创建成功 400:错误请求 注意:当axios遇到4开头的时候就会认为请求失败了,如下代码中:

/**
 * 响应拦截器
 */
axios.interceptors.response.use((response) => {
  loadingClose();
  if (response.status === 200 || response.status === 201) {
    response.data = common.jsonNullToEmpty(response.data);
    let message = resultValid(response.data, axiosInfo.services);

    if (message !== "" && message !== undefined) {
      Global.messageErr(message);
      return Promise.reject(message);
    }
    return response;
  }
}, (error) => {
  const errorCodeMap =  {
    100100: '请求参数缺失或格式不正确',
    100400: '请求的数据不存在',
    100500: '数据已存在'
  }
  Global.messageErr(errorCodeMap[error.response.data.respCode] || '服务器错误,请联系管理员');
  Promise.reject(error)
})

当返回的status为400的时候,会进入到拦截器的失败回调中,而此时想要拿到后端给返回的状态码,需要通过error对象获取。error对象的response属性对应一个对象是服务端返回响应的数据,在这里后端返回的是 data, 包括respCode和respMsg。

参考资料:

文章转自微信公众号@重温新知

#你可能也喜欢这些API文章!