axios把post的RequestPayload格式转为formdata

28 篇文章 1 订阅

方法一:配置transformRequest,缺点:其他请求格式的数据也会被重新格式化(PUT,PATCH)

const service = axios.create({
    //设置axios为form-data 方法1
    // headers: {
    //     post: {
    //         "Content-Type": "application/x-www-form-urlencoded"
    //     },
    //     get: {
    //         "Content-Type": "application/x-www-form-urlencoded"
    //     }
    // },
        transformRequest: [function (data) {
        let request = ''
        for (let item in data) {
            if (data[item])
                request += encodeURIComponent(item) + '=' + encodeURIComponent(data[item]) + '&'
        }
        return request.slice(0, request.length - 1)
    }]
})

方法二:添加请求拦截器,对症下药(推荐),所有主要浏览器都支持 encodeURIComponent() 函数

//添加请求拦截器
service.interceptors.request.use(
    config => {
        //设置axios为form-data 方法2
        if (config.method === 'post') {
            let data = ''
            for (let item in config.data) {
                if (config.data[item])
                    data += encodeURIComponent(item) + '=' + encodeURIComponent(config.data[item]) + '&'
            }
            config.data = data.slice(0, data.length - 1)
        }
        return config;
    },
    error => {
        console.log("在request拦截器显示错误:", error.response)
        return Promise.reject(error);
    }
);

方法三:添加请求拦截器,使用axios 插件qs转换,可能存在兼容性问题

import qs from 'qs';
//添加请求拦截器
service.interceptors.request.use(
    config => {
        //设置axios为form-data 方法2
        if (config.method === 'post') {
            config.data = qs.stringify(config.data); // npm install axios qs --save
        }
        return config;
    },
    error => {
        console.log("在request拦截器显示错误:", error.response)
        return Promise.reject(error);
    }
);

完整代码:

import axios from 'axios'
import store from '@/store'
import router from '@/router'
import Vue from "vue";
// import qs from 'qs';
let vue = new Vue()

// create an axios instance
const service = axios.create({
    // index.js设置了代理(解决跨域) api = XXX
    baseURL: "/api", // url = base url + request url
    timeout: 5000, // request timeout
    // headers: {
    //     Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    //     Cookie: "JSESSIONID=8F611FDFEBA4FA2A1891D5929F5E8682",
    //     "Upgrade-Insecure-Requests": 1,
    //     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"
    // }
    //设置axios为form-data 方法1
    // headers: {
    //     post: {
    //         "Content-Type": "application/x-www-form-urlencoded"
    //     },
    //     get: {
    //         "Content-Type": "application/x-www-form-urlencoded"
    //     }
    // },
    // transformRequest: [function (data) {
    //     let request = ''
    //     for (let item in data) {
    //         if (data[item])
    //             request += encodeURIComponent(item) + '=' + encodeURIComponent(data[item]) + '&'
    //     }
    //     return request.slice(0, request.length - 1)
    // }]
})

//添加请求拦截器,若token存在则在请求头中加token,不存在也继续请求
service.interceptors.request.use(
    config => {
        // 每次发送请求之前检测都vuex存有token,那么都要放在请求头发送给服务器,没有则不带token
        // Authorization是必须的
        // if (store.getters.getToken) {
        //     config.headers.Authorization = store.getters.getToken;
        // }
        vue.$Loading.start()
        //设置axios为form-data 方法2
        if (config.method === 'post') {
            // config.data = qs.stringify(config.data); // npm install axios qs --save
            let data = ''
            for (let item in config.data) {
                if (config.data[item])
                    data += encodeURIComponent(item) + '=' + encodeURIComponent(config.data[item]) + '&'
            }
            config.data = data.slice(0, data.length - 1)
        }
        return config;
    },
    error => {
        console.log("在request拦截器显示错误:", error.response)
        vue.$Loading.error()
        return Promise.reject(error);
    }
);

//respone拦截器
service.interceptors.response.use(
    response => {
        vue.$Loading.finish();
        // 在status正确的情况下,code不正确则返回对应的错误信息(后台自定义为200是正确,并且将错误信息写在message),正确则返回响应
        return response.data;
    },
    error => {
        vue.$Loading.error()
        // 在status不正确的情况下,判别status状态码给出对应响应
        if (error.response) {
            console.log("在respone拦截器显示错误:", error.response)
            switch (error.response.status) {
                case 401:
                    //可能是token过期,清除它
                    store.commit("delToken");

                    router.replace({ //跳转到登录页面
                        path: '/login',
                        // 将跳转的路由path作为参数,登录成功后跳转到该路由
                        query: { redirect: router.currentRoute.fullPath }
                    });
            }
        }
        return Promise.reject(error.response);
    }
);


export default service




// axios({
//     url:'/user',                            //  `url`是服务器链接,用来请求用
//     method:`get`,                           //  `method`是发起请求时的请求方法
//     baseURL:'http://some-domain.com/api/',  //  `baseURL`如果`url`不是绝对地址,那么将会加在其前面。当axios使用相对地址时这个设置非常方便
 
//     transformRequest:[function(data){       //  `transformRequest`允许请求的数据在传到服务器之前进行转化。只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法。数组中的最后一个函数必须返回一个字符串,一个`ArrayBuffer`,或者`Stream`
//         //依自己的需求对请求数据进行处理
//         return data;
//     }],
//     transformResponse:[function(data){      //  `transformResponse`允许返回的数据传入then/catch之前进行处理
//         //依需要对数据进行处理
//         return data;
//     }],  
//     headers:{'X-Requested-with':'XMLHttpRequest'},//`headers`是自定义的要被发送的头信息
//     params:{ //`params`是请求连接中的请求参数,必须是一个纯对象,或者URLSearchParams对象
//         ID:12345
//     },
//     paramsSerializer: function(params){//`paramsSerializer`是一个可选的函数,是用来序列化参数,例如:(https://ww.npmjs.com/package/qs,http://api.jquery.com/jquery.param/)
//         return Qs.stringify(params,{arrayFormat:'brackets'})
//     },
//     data:{//`data`是请求提需要设置的数据,只适用于应用的'PUT','POST','PATCH',请求方法。当没有设置`transformRequest`时,必须是以下其中之一的类型(不可重复?):-string,plain object,ArrayBuffer,ArrayBufferView,URLSearchParams。仅浏览器:FormData,File,Blob。仅Node:Stream
//         firstName:'fred'
//     },
//     //`timeout`定义请求的时间,单位是毫秒。
//     //如果请求的时间超过这个设定时间,请求将会停止。
//     timeout:1000,
//     //`withCredentials`表明是否跨域请求,
//     //应该是用证书
//     withCredentials:false //默认值
//     //`adapter`适配器,允许自定义处理请求,这会使测试更简单。
//     //返回一个promise,并且提供验证返回(查看[response docs](#response-api))
//     adapter:function(config){
//         /*...*/
//     },
//     //`auth`表明HTTP基础的认证应该被使用,并且提供证书。
//     //这个会设置一个`authorization` 头(header),并且覆盖你在header设置的Authorization头信息。
//     auth:{
//         username:'janedoe',
//         password:'s00pers3cret'
//     },
//     //`responsetype`表明服务器返回的数据类型,这些类型的设置应该是
//     //'arraybuffer','blob','document','json','text',stream'
//     responsetype:'json',
//     //`xsrfHeaderName` 是http头(header)的名字,并且该头携带xsrf的值
//     xrsfHeadername:'X-XSRF-TOKEN',//默认值
//     //`onUploadProgress`允许处理上传过程的事件
//     onUploadProgress: function(progressEvent){
//         //本地过程事件发生时想做的事
//     },
//     //`onDownloadProgress`允许处理下载过程的事件
//     onDownloadProgress: function(progressEvent){
//         //下载过程中想做的事
//     },
//     //`maxContentLength` 定义http返回内容的最大容量
//     maxContentLength: 2000,
//     //`validateStatus` 定义promise的resolve和reject。
//     //http返回状态码,如果`validateStatus`返回true(或者设置成null/undefined),promise将会接受;其他的promise将会拒绝。
//     validateStatus: function(status){
//         return status >= 200 &;&; stauts < 300;//默认
//     },
//     //`httpAgent` 和 `httpsAgent`当产生一个http或者https请求时分别定义一个自定义的代理,在nodejs中。
//     //这个允许设置一些选选个,像是`keepAlive`--这个在默认中是没有开启的。
//     httpAgent: new http.Agent({keepAlive:treu}),
//     httpsAgent: new https.Agent({keepAlive:true}),
//     //`proxy`定义服务器的主机名字和端口号。
//     //`auth`表明HTTP基本认证应该跟`proxy`相连接,并且提供证书。
//     //这个将设置一个'Proxy-Authorization'头(header),覆盖原先自定义的。
//     proxy:{
//         host:127.0.0.1,
//         port:9000,
//         auth:{
//             username:'cdd',
//             password:'123456'
//         }
//     },
//     //`cancelTaken` 定义一个取消,能够用来取消请求
//     //(查看 下面的Cancellation 的详细部分)
//     cancelToke: new CancelToken(function(cancel){
//     })
// });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值