vue+axios通过formdata提交参数和上传文件

demo.vue 文件

<template>
    <div class="demo">
        <input v-model="importForm.month" type="text" name="month"/>    
        <input ref="importFile" type="file" name="importFile" @change="handleFileChange" />
        <button @click="handleConfimImport">确认导入</button>
    </div>
</template>

<script>
    export default {
        name: 'profitLossTree',
        components: {},
        data(){
            return {
                importForm: {
                    month: '',
                    importFile: '',
                },
            }
        },
        computed: {},
        watch: {},
        methods: {

            //导入文件改变
            handleFileChange(){
                console.log(this.$refs.importFile.files[0]);
                this.importForm.importFile = this.$refs.importFile.files[0];
                // console.log(this.importForm, '改变');
            },
            // 确认导入
            handleConfimImport(name){
/*              //提取到 post_formData 方法中
                // vue 中使用 window.FormData(),否则会报 'FormData isn't definded'
                //创建一个FormData对象,然后通过append() 方法向对象中添加键值对
                let formData = new window.FormData();
                formData.append("month", this.importForm.month);
                formData.append("importFile", this.importForm.importFile);
                console.log('formData', formData);  //formData中的参数是隐式的直接看不到, 可以通过formData 实例的get方法获取
                console.log('formData--month', formData.get('month'));
                console.log('formData--importFile', formData.get('importFile'));
                this.$post_formData( '/profitLossController/importDataNew', 
                    formData 
                ).then( res => {
                    this.$Message.success('导入成功!');
                }) .catch( error => {
                    this.$Message.error("请求数据出错");
                });
            }
*/

                this.$post_formData('/profitLossController/importDataNew', { 
                    'month': this.importForm.month , 
                    'importFile': this.importForm.importFile
                }).then( res => {
                    this.$Message.success('导入成功!');
                }) .catch( error => {
                    this.$Message.error("请求数据出错");
                });
        },
        mounted(){

        }
    };
</script>

<style scoped>

</style>
View Code

对axios进行封装的http.js文件

import axios from 'axios';
import property from './property'; //引用基础配置文件
import util from './util'; //引用刚才我们创建的util.js文件,并使用getCookie方法
import qs from 'qs';
import Cookies from 'js-cookie';
// axios 配置
axios.defaults.timeout = 30000;
axios.defaults.baseURL = util.api; //这是调用数据接口
axios.defaults.withCredentials = true;
axios.defaults.headers = {
  'Content-Type': 'application/json' //设置跨域头部
};

// http request 拦截器,通过这个,我们就可以把Cookie传到后台
axios.interceptors.request.use(
    config => {
      const token = Cookies.get('user'); //获取Cookie
      if (token) {
        config.headers.token = token;
       // config.params = {'token': token}; //后台接收的参数,后面我们将说明后台如何接收
        /**
         * 原axios封装的时候对所有的请求请求 进行 JSON 转换,会破坏掉 formdata 提交数据,
         * 所以可以通过axios.create() 创建一个新的实例(axiosInstanceNew)进行 formdata提交,见下
         */
        config.data = JSON.stringify(config.data); 
        //将get请求的参数进行序列化,主要处理数组传值问题
        config.paramsSerializer = function(params) {
            return qs.stringify(params, {indices: false});   
          }
      } else {
        if (!util.oneOf(config.url, property.noTokenUrl)) {
          location.reload();
        }
      }
      return config;
    },
    err => {
      return Promise.reject(err);
    }
);

// http response 拦截器
axios.interceptors.response.use(
    response => {
//response.data.errCode是我接口返回的值,如果值为2,说明Cookie丢失,然后跳转到登录页,这里根据大家自己的情况来设定
      // if(response.data.errCode == 2) {
      // router.push({
      // path: '/login',
      // query: {redirect: router.currentRoute.fullPath}  //从哪个页面跳转
      // })
      // }
      return response;
    },
    error => {
      switch (error.response.status) {
        case 401:
          Cookies.remove('user');
          if (!util.oneOf(error.config.url.substring(util.api.length), property.noTokenUrl)) {
            location.reload();
          }
          break;
        // case 404:
        //
        //   break;
        // case 500:
        //
        //   break;
        default:
            alert(`请求出错!请求状态码:${error.response.status}。`);
      }
      return error;
      // if(error.response.status == 401){
      //     //this.$Message.error('32131');
      //     //util.delCookie('user');
      //    Cookies.remove('user')
      //     location.reload();
      // }else{
      //     alert("请求出错!");
      // }
      //return Promise.reject(error.response.data)
    });

export default axios;
// -------------------------------
//创建新的axios
//创建一个新的axios实例
const axiosInstanceNew = axios.create({
    baseURL: util.api,
    timeout: 30000,
    withCredentials: true
});

//新axios实例拦截
// http request 拦截器,通过这个,我们就可以把Cookie传到后台
axiosInstanceNew.interceptors.request.use( config => {
        const token = Cookies.get('user'); //获取Cookie
        if (token) {
            config.headers.token = token;
            //将get请求的参数进行序列化,主要处理数组传值问题
            config.paramsSerializer = function(params) {
                return qs.stringify(params, {indices: false});
            }
        } else {
            if (!util.oneOf(config.url, property.noTokenUrl)) {
                location.reload();
            }
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    }
);

// 新 http response 拦截器
axiosInstanceNew.interceptors.response.use( response => {
//response.data.errCode是我接口返回的值,如果值为2,说明Cookie丢失,然后跳转到登录页,这里根据大家自己的情况来设定
        // if(response.data.errCode == 2) {
        // router.push({
        // path: '/login',
        // query: {redirect: router.currentRoute.fullPath}  //从哪个页面跳转
        // })
        // }
        return response;
    }, error => {
        switch (error.response.status) {
            case 401:
                Cookies.remove('user');
                if (!util.oneOf(error.config.url.substring(util.api.length), property.noTokenUrl)) {
                    location.reload();
                }
                break;
            // case 404:
            //
            //   break;
            // case 500:
            //
            //   break;
            default:
                alert(`请求出错!请求状态码:${error.response.status}。`);
        }
        return error;
        // if(error.response.status == 401){
        //     //this.$Message.error('32131');
        //     //util.delCookie('user');
        //    Cookies.remove('user')
        //     location.reload();
        // }else{
        //     alert("请求出错!");
        // }
        //return Promise.reject(error.response.data)
    });


/**
 * post 请求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post (url, data = {}) {
  axios.defaults.withCredentials = true;
  return new Promise((resolve, reject) => {
    axios.post(url, data)
        .then(response => {

          resolve(response.data);
        }, err => {

          reject(err);
        });
  });
}
/**
 * post 请求方法  提交格式为 formdata
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post_formData (url, data = {}) {

    // vue 中使用 window.FormData(),否则会报 'FormData isn't definded'
    //创建一个FormData对象,然后通过append() 方法向对象中添加键值对
    // let formData = new window.FormData();
    let formData = new FormData(); //这里是 .js文件
    for ( let key in data ){
        formData.append( key, data[key]);
    }

    const options = {
        method: 'POST',
        // headers: { 'content-type': 'application/x-www-form-urlencoded' },
        headers: { 'Content-type': 'multipart/form-data' },
        // data: qs.stringify(data),
        data: formData,
        url,
    };
    return axiosInstanceNew(options);
}
View Code

说明:注意上面代码有这行注释的地方

        /**
         * 原axios封装的时候对所有的请求请求 进行 JSON 转换,会破坏掉 formdata 提交数据,
         * 所以可以通过axios.create() 创建一个新的实例(axiosInstanceNew)进行 formdata提交,见下
         */
为什么要创建一个新的axios实例的可以参考这篇文章:
 https://blog.csdn.net/qq_41688165/article/details/80834842 

在main.js中挂载到了vue实例原型上

import { post, post_formData } from './libs/http';
Vue.prototype.$post_formData = post_formData;

这样基本上就可以了。请求时参数直接传入一个对象就可以了。