阅读 1724

更优雅的HTTP请求

四个文件一篇文,一个工具一框架, 工具:axios 框架:vue为例

四个文件

└─src               
    ├─services          // 目录
    ├─  api.js          // api管理
    ├─  axios.js     	// axios请求
    ├─  fetch.js     	// 二次封装
    ├─  request.js     	// 请求方式管理
复制代码
  • api.js 存放所有的接口请求
  • axios.js 请求拦截处理
  • fetch.jsaxios请求的二次封装
  • request.js管理请求方式get post put delete...

axios.js

import axios from 'axios'
import { getToken } from '@/utils/token'

// axios baseURL 
axios.defaults.baseURL = process.env.VUE_APP_BASE_API

const instance = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,    // 实例 baseURL
  timeout: 6000
})

instance.interceptors.request.use(config => {
  const token = getToken()
  token && (config.headers['X-Access-Token'] = token)
  
  return config
}, err => {
  return Promise.reject(err)
})

instance.interceptors.response.use(res => {
  /* 错误处理 */
  // ......

  return res
}, err => {
  return Promise.reject(err)
})

export default instance

复制代码

创建一个axios实例,定义baseURL,也可以使用process.env.NODE_ENV来做开发环境和生产环境的判断

之前

每个有请求的文件中import axios from 'axios',或者 Vue.prototype.$axios = axios,使用时$axios.get(url, params)

现在

👇

fetch.js

稍作处理下

/**
 * fetchData
 * @param {String} url 请求地址
 * @param {String} method 请求方式
 * @param {Object} data 请求参数
 * @returns res.data
 */

import http from './axios'
import Qs from 'qs'

export const fetchData = async (url, method, data = null) => {
  let httpOpts = { url, method }
  httpOpts = method === 'get' ? { 
    ...httpOpts, 
    params: data,
    paramsSerializer: params => Qs.stringify(params, { indices: false })  // 序列化 处理数组
  } : { ...httpOpts, data }

  try {
    const res = await http(httpOpts)
    return res.data
  } catch (error) {
    return null
  }
  
  // 使用 .then .catch 情况
  // return http(httpOpts).then(res => {
    // return res.data
  // }).catch(err => {
    // return null
  // })
}
复制代码

目前仅对getpost请求做了处理,可以根据实际情况来添加其他请求方式put delete 对于get请求在这做了数组类型参数序列化的处理

众所周知axios请求成功返回的结果中我们所需要的数据在data中,所以我们在这直接返回res.data,再或者在axios的响应拦截器中返回res.data

request.js

fetch.js中既然区分开了getpost请求,那么...

/**
 * 请求方式
 * @param url 请求接口路径
 * @param data 请求参数
 * @method getRequest get请求
 * @method postRequest post请求
 */

import { fetchData } from './fetch'

export const getRequest = (url, data) => fetchData(url, 'get', data)   // get请求
export const postRequest = (url, data) => fetchData(url, 'post', data) // post请求

// export const putRequest = (url, data) => fetchData(url, 'put', data)   // put请求
// export const deleteRequest = (url, data) => fetchData(url, 'delete', data) // delete请求
复制代码

我们定义了getRequestpostRequest方法,这两个方法都接收两个参数,分别为urldata,返回一个函数,就是在fetch.js中定义的fetchData,把接收的两个参数传给fetchData

api.js

最后到了请求接口环节,将所有接口统一放在api.js中管理 request.js中的urldata来自于这

/**
 * 所有接口请求
 */

import { getRequest, postRequest } from './request'

/* 登录注册 */
export const login = data => postRequest('/login', data)
export const register = data => postRequest('/register', data)

// export const xxx = data => deleteRequest('/xxx', data)
// export const xxx = data => putRequest('/xxx', data)

/* 文章接口 */
export const articleList = data => getRequest('/article/list', data)

......
复制代码

使用

import { articleList } from '@/services/api'

async getArticleList() {
  const res = await articleList(params)
}
复制代码

现在在组件中我们只关心接口所需要传递的参数,不再需要写请求路径以及请求方式,这些全部交给上面4个文件处理

整体流程

  1. 创建axios实例
  2. 根据请求方式,对请求稍作处理,并将请求结果返回
  3. 定义不同请求方式的方法
  4. 请求地址和方式不再在组件中书写,统一在一个文件中管理
  5. 组件中导入要使用的方法即可,只需关心参数,不再关心其他