Vue封装网络请求

一般我们会在src目录下新建http.js和api.js
http.js网络请求的封装
api.js接口的封装

http.js

import axios from 'axios'
import {
     Loading, Message} from 'element-ui'    // 这里我是使用elementUI的组件来给提示
// import router from '@/router'


let loadingInstance = null     // 加载全局的loading


const instance = axios.create({
         //创建axios实例,在这里可以设置请求的默认配置
    timeout: 1000 * 30, // 设置超时时间10s
    baseURL: '/',   //根据自己配置的反向代理去设置不同环境的baeUrl
})


// 文档中的统一设置post请求头。下面会说到post请求的几种'Content-Type'
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// instance.defaults.proxy

let httpCode = {
             //这里我简单列出一些常见的http状态码信息,可以自己去调整配置
    400: '请求参数错误',
    401: '权限不足, 请重新登录',
    403: '服务器拒绝本次访问',
    404: '请求资源未找到',
    500: '内部服务器错误',
    501: '服务器不支持该请求中使用的方法',
    502: '网关错误',
    504: '网关超时'
}

/**
 * 根据cookie名,获取cookie
 * @param name 
 * @returns {null}
 */
function getCookie(name) {
     
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
     
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
     
            var cookie = cookies[i].trim()
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
     
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}


function csrfSafeMethod(method) {
     
    // 这些HTTP方法不要求CSRF包含
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

/** 添加请求拦截器 **/
instance.interceptors.request.use(config => {
     
    config.headers['X-CSRFToken'] = getCookie('csrftoken') || ''
    loadingInstance = Loading.service({
            // 发起请求时加载全局loading,请求失败或有响应时会关闭
        spinner: 'fa fa-spinner fa-spin fa-3x fa-fw',
        text: '拼命加载中...'
    })
    // 在这里:可以根据业务需求可以在发送请求之前做些什么:例如我这个是导出文件的接口,因为返回的是二进制流,所以需要设置请求响应类型为blob,就可以在此处设置。
    if (config.url.includes('pur/contract/export')) {
     
        config.headers['responseType'] = 'blob'
    }
    // 我这里是文件上传,发送的是二进制流,所以需要设置请求头的'Content-Type'
    if (config.url.includes('pur/contract/upload')) {
     
        config.headers['Content-Type'] = 'multipart/form-data'
    }
    return config
}, error => {
     
    // 对请求错误做些什么
    return Promise.reject(error)
})

/** 添加响应拦截器  **/
instance.interceptors.response.use(response => {
     
    loadingInstance.close()
    return Promise.resolve(response.data)
    // if (response.data.status === 'ok') {     // 响应结果里的status: ok是我与后台的约定,大家可以根据实际情况去做对应的判断
    //     return Promise.resolve(response.data)
    // } else {
     
    //     Message({
     
    //         message: response.data.message,
    //         type: 'error'
    //     })
    //     return Promise.reject(response.data.message)
    // }
}, error => {
     
    loadingInstance.close()
    if (error.response) {
     
        // 根据请求失败的http状态码去给用户相应的提示
        let tips = error.response.status in httpCode ? httpCode[error.response.status] : error.response.data.message
        Message({
     
            message: tips,
            type: 'error'
        })
        if (error.response.status === 401) {
         // token或者登陆失效情况下跳转到登录页面,根据实际情况,在这里可以根据不同的响应错误结果,做对应的事。这里我以401判断为例
            // router.push({
     
            //     path: `/login`
            // })
        }
        return Promise.reject(error)
    } else {
     
        Message({
     
            message: '请求超时, 请刷新重试',
            type: 'error'
        })
        return Promise.reject(new Error('请求超时, 请刷新重试'))
    }
})

/* 统一封装get请求 */
export const get = (url, params, config = {
     }) => {
     
    return new Promise((resolve, reject) => {
     
        instance({
     
            method: 'get',
            url,
            params,
            ...config
        }).then(response => {
     
            resolve(response)
        }).catch(error => {
     
            reject(error)
        })
    })
}

/* 统一封装post请求  */
export const post = (url, data, config = {
     }) => {
     
    return new Promise((resolve, reject) => {
     
        instance({
     
            method: 'post',
            url,
            data,
            ...config
        }).then(response => {
     
            resolve(response)
        }).catch(error => {
     
            reject(error)
        })
    })
}

export const axiosInstance = instance;

/* 或者写成下面这样: Promise.resolve() 和 Promise.reject()返回的是promise对象,二者都是语法糖  */
// export const post = (url, data, config = {}) => {
     
//     return instance({
     
//         method: 'post',
//         url,
//         data,
//         ...config
//     }).then(response => {
     
//         return Promise.resolve(response)
//     }).catch(error => {
     
//         return Promise.reject(error)
//     })
// }

api.js

import {
     get} from "@/request/http";

/**
 * 
 * @param p 
 * @returns {Promise}
 */
export const test = p => get('/test', p);

vue.config.js

module.exports = {
     
    lintOnSave: 'warning'
}


// const path = require('path')
const Terser = require('terser-webpack-plugin')

// const resolve = dir => path.join(__dirname, dir)

/**
 * 环境根目录
 */
// let BaseURL = {
     
//     prod: 'http://localhost:8000',
//     dev: 'http://localhost:8000',
// }

const URL = "http://xxx:xx";

module.exports = {
     
    lintOnSave: false,//取消Eslint检测
    productionSourceMap: false,
    publicPath: process.env.NODE_ENV === 'production'
        ? '/'
        : '/',
    configureWebpack: config => {
     
        const plugins = [
            new Terser({
     
                terserOptions: {
     
                    output: {
     
                        // 删除注释
                        comments: false
                    },
                    compress: {
     
                        warnings: false,
                        // 删除 console
                        // drop_console: true
                        pure_funcs: ['console.log', 'console.warn', 'console.info']
                    }
                }
            })
        ]

        // 只有打包生产环境才需要将console删除
        if (process.env.NODE_ENV === 'production') {
     
            config.plugins = [...config.plugins, ...plugins]
        }
    },


    devServer: {
     
        open: false,
        disableHostCheck: true,
        proxy: {
     
            '/': {
     
                target: URL,
            }

        }
    }
}

调用的地方:

import {
     test} from "@/request/api";
let params = 
{
     
     xx: ''
}
test(params).then(r => {
     
    console.log(r)
})

你可能感兴趣的:(Vue)