Axios secondary packaging, fetch packaging, and api interface management specifications

The advantages and disadvantages of jQuery's ajax, axios and fetch

1.jQuery ajax

$.ajax({
    
    
   type: 'POST',
   url: url,
   data: data,
   dataType: dataType,
   success: function () {
    
    },
   error: function () {
    
    }
});

Advantages and disadvantages:

  • It is programming for MVC, which does not meet the current wave of front-end MVVM

  • Based on the original XHR development, the architecture of XHR itself is not clear, and there is an alternative to fetch

  • The whole project of JQuery is too big, it is very unreasonable to use Ajax to introduce the whole JQuery (it is not possible to enjoy the CDN service with a personalized package)

2.axios

axios({
    
    
    method: 'post',
    url: '/user/12345',
    data: {
    
    
        firstName: 'Fred',
        lastName: 'Flintstone'
    }
})
.then(function (response) {
    
    
    console.log(response);
})
.catch(function (error) {
    
    
    console.log(error);
});

Advantages and disadvantages:

  • Create http request from node.js
  • Support Promise API
  • The client supports CSRF (Cross Site Request Forgery)
  • Provides some concurrent request interfaces (important, convenient for many operations)

3.fetch

try {
    
    
  let response = await fetch(url);
  let data = response.json();
  console.log(data);
} catch(e) {
    
    
  console.log("Oops, error", e);
}

Advantages and disadvantages:

  • In line with separation of concerns, there is no mixing of input, output, and the state tracked by events in one object
  • Better and more convenient writing
  • More low-level, rich API (request, response)
  • Departed from XHR, it is a new implementation in the ES specification
  • 1) fetcht only reports errors for network requests, 400 and 500 are regarded as successful requests and need to be encapsulated for processing
  • 2) fetch does not carry cookies by default, and configuration items need to be added
  • 3) Fetch does not support abort and timeout control. The timeout control implemented using setTimeout and Promise.reject cannot prevent the request process from continuing to run in the background, resulting in a waste of volume
  • 4) fetch has no way to monitor the progress of the request natively, while XHR can

Key axios secondary packaging

import axios from 'axios'
import qs from 'qs'
switch (process.env.NODE_ENV) {
    
    
    case "production":
        axios.defaults.baseURL = "http.....";
    case "test":
        axios.defaults.baseURL = "http.....";
    default:
        axios.defaults.baseURL = 'http'
}
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;

axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.transfromRequest = data => qs.stringify(data);
axios.interceptors.request.use(config => {
    
    
        let token = localStorage.getItem('token');
        token && (config.headers.Authorization = token);
        return config;
    }, error => {
    
    
        //如果拦截失败返回失败信息
        return Promise.reject(error)
    })
    /*
     *响应拦截器
     * 服务器返回信息 ->[拦截的统一处理] -> 客户端js获取到信息
     */
    // axios.defaults.validateStatus = status => {
    
    
    //     //自定义响应成功的http状态码,默认只有2或者3开头的响应码
    //     return /^(2|3)\d{2}$/.test(status)
    // }
axios.interceptors.response.use(response => {
    
    
    return response.data; //只返回响应的主体内容
}, error => {
    
    
    if (error.response) {
    
    
        //如果服务器有返回信息
        switch (error.response.status) {
    
    
            case 401: //当前请求需要用户验证(一般是未登录)
                break;
            case 403: //服务器已经理解请求,但是拒绝执行他(一般是TOKEN过期)
                localStorage.removeItem('token');
                //跳转的登录页面
                break;
            case 404: //请求失败,请求所希望的到的资源未被在服务器上发现
                break;
        }
        return Promise.reject(error, response)
    } else {
    
     // 如果服务器没有返回信息
        //断网处理
        if (!window.navigator.onLine) {
    
    
            //网络断开了,可以让其跳转到断网页面
            return
        }
        return Promise.reject(error)
    }
})
export default axios

Fetch package

import qs from 'qs'
import {
    
     delete } from 'vue/types/umd';
/*
 * 根据环境变量进行接口区分
 */
let baseURL = '';
let baseURLArr = [{
    
    
    type: 'development',
    url: 'http://127.0.0.1:8080'
}, {
    
    
    type: 'test',
    url: 'http://XXXX'
}, {
    
    
    type: 'production',
    url: 'http://XXXX'
}];
baseURLArr.forEach(item => {
    
    
    if (process.env.NODE_ENV === item.type) {
    
    
        baseURL = item.url;
    }
})
export default function request(url, options = {
    
    }) {
    
    
    url = baseURL + url;
    /*
     * GET 系列请求的处理
     * 正常请求 request(url,{
     * params:{
     *      method:'get'
     *  }
     * })
     */
    !options.method ? options.method = 'GET' : null;
    if (options.hasOwnProperty('params')) {
    
    
        if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(options.method)) {
    
    
            const ask = url.includes('?') ? '&' : '?';
            url += `${
      
      ask}${
      
      qs.stringify(params)}`;
        }
        delete options.params; //应为fetch中没有params,所以用完后赢移除
    }
    /*
     * 合并配置项
     */
    options = Object.assign({
    
    
        //允许跨域携带资源凭证 same-origin 同源可以 omit都拒绝
        credentials: 'include', //不管同源不同元都可以携带资源凭证
        //设置请求头
        headers: {
    
    }
    }, options);
    options.headers.Accept = 'application/json';
    /*
     *token的校验
     */
    const token = localStorage.getItem('token');
    token && (options.headers.Authorization = token);

    /*
     * post 请求的处理
     */
    if (/^(POST|PUT)$/i.test(options.method)) {
    
    
        !options.type ? options.type = 'urlencoded' : null;
        if (options.type === 'urlencoded') {
    
    
            options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
            options.body = qs.stringify(options.body);
        }
        if (options.type === 'json') {
    
    
            options.headers['Content-Type'] = 'application/json';
            options.body = JSON.stringify(options.body);
        }
    }
    return fetch(url, options).then(response => {
    
    
        if (!/^(2|3)\d$/.test(response.status)) {
    
    
            switch (response.status) {
    
    
                case 401: //当前请求需要用户验证(一般是未登录)
                    break;
                case 403: //服务器已经理解请求,但是拒绝执行他(一般是TOKEN过期)
                    localStorage.removeItem('token');
                    //跳转的登录页面
                    break;
                case 404: //请求失败,请求所希望的到的资源未被在服务器上发现
                    break;
            }
        }
        return response.json()
    }).catch(error => {
    
    
        if (!window.navigator.onLine) {
    
    
            //网络断开了,可以让其跳转到断网页面
            return;
        }
        return Promise.reject(error);
    })
}

Centralized management of api

Put the module interface in a file for centralized management,
Insert picture description here
such as user.js

import Axios from "../utile/Axios"
//导入封装好的axios
/*
 * 用户页面的所有接口
 * 获得用户信息
 */
export const GetUserInfo = () => {
    
    
        return new Promise((resolve, reject) => {
    
    
            Axios.get('/member/ajax_login.php')
                .then(res => resolve(res))
                .catch(err => reject(err))
        })
    }
    /*
     * 用户退出
     */
export const Exit = () => {
    
    
        return new Promise((resolve, reject) => {
    
    
            Axios.post("/member/index_login.php", {
    
     dopost: 'exit' })
                .then(res => resolve(res))
                .catch(err => reject(err))
        })
    }
    /*
     * 用户页面头部信息
     */
export const GetUserList = () => {
    
    
        return new Promise((resolve, reject) => {
    
    
            Axios.get('http://www.xingzhuang.com/user/list')
                .then(res => resolve(res))
                .catch(err => reject(err))
        })
    }
    /*
     *  用户下方产品列表
     */
export const getUserGoodsList = () => {
    
    
    return new Promise((resolve, reject) => {
    
    
        Axios.post('/html/recommend/getRecommendGoodsList', {
    
     siteId: 3, pageSize: 20, pageNum: 1 }
                //pageNum为参数
            ).then(res => resolve(res))
            .catch(err => reject(err))
    })
}

Centralized import in the api.js file

/*
 * 项目接口的唯一入口
 */
import {
    
     GetUserInfo, Exit, GetUserList, getUserGoodsList } from './user'
import {
    
     Category, GetMan, GetSelectind } from './cat'
export default {
    
    
    GetUserInfo,
    Exit,
    GetUserList,
    getUserGoodsList,

    Category,
    GetMan,
    GetSelectind
}

Can be imported in main.js

import api from '../src/api/api'
Vue.prototype.$api = api

If you want to use the Exit method at the user module at this time, you only need

 this.$api.Exit()

Greatly facilitate the convenience of interface management

Guess you like

Origin blog.csdn.net/qq_47008195/article/details/108687623