继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

深陷axios坑中,久久不得爬出,望君莫犯!

张培跃
关注TA
已关注
手记 23
粉丝 30
获赞 98

本人一生与bug英勇奋战,可谓斩敌无数,双手沾满鲜血,对于bug早已见怪不怪了。怎奈对于一些始料未及,史无前例的另类bug,真是惊呆了我的小伙伴们!

我在使用axios的过程中,遇神坑一个,坑虽不大,但深陷其中并久久不得爬出。在此记录一下,望君莫犯!


一切的一切,都要从axios的transformRequest属性说起…

一、transformRequest的四个特征:

1、可以在向服务器发送请求数据之前,修改请求数据。

2、函数必须要返回一个字符串或 ArrayBuffer或 Stream。

3、该函数只适用于 POST,PUT,PATCH请求方式

4、默认Content-Type值为:application/x-www-form-urlencoded

axios({
    method:"post",
    url:"http://127.0.0.1/sum",
    data:"a=1&b=2",
    transformRequest(data) {
        return data
    }
}).then(data => {
    console.log(data);
})

虽然以上代码运行不会有任何的问题,但作为一名出色的开发者,所考虑的情形一定要全面!

例如,我想修改Content-Type的值为application/json该如何处理?我第一想到的方法便是为其增加headers属性,于是将代码打造为:

axios({
    method:"post",
    url:"http://127.0.0.1/sum",
    data:{
        a:1,
        b:2
    },
    headers:{
        "content-type":"application/json"
    },
    transformRequest(data) {
        return JSON.stringify(data);
    }
}).then(data => {
    console.log(data);
})

经过以上的改造,我成功的让服务器无法接收到请求的数据了!

哎!问题究竟出在哪里?经拷问Network得知,content-type居然变成了下图的惨烈样子!

image

于是乎,我开始尝试各种方法并利用各种搜索引擎来查找问题元凶,无果!

没办法,我现在只能对axios的源码进行阅读了(在此也深感阅读源码的重要性)。

随着时间的消磨推移,终于让我找到了问题的真正原因所在!并思考出三种技术解决方案!嗯,没错!是三种!

二、解决方案一

1、必须,必须,必须要设置请求头!

// 可以通过这种方式给axios设置的默认请求头
axios.defaults.headers = {
    "content-type":"application/json"
}

2、代码修改为:

axios({
    method:"post",
    url:"http://127.0.0.1/sum",
    data:{
        a:1,
        b:2
    },
    transformRequest(data) {
        return JSON.stringify(data);
    }
}).then(data => {
    console.log(data);
})

因为默认值已经设置为json,所以将代码中的headers属性移除掉了。

自此,设置完默认请求头后,我的headers以后便可以任意修改了!

三、解决方案二

注意Content-Type的大小写,大小写,大小写……

代码修改为:

axios({
    method:"post",
    url:"http://127.0.0.1/sum",
    data:{
        a:1,
        b:2
    },
    headers:{
        "Content-Type":"application/json"
    },
    transformRequest(data,headers) {
        return JSON.stringify(data);
    }
}).then(data => {
    console.log(data);
})
四、解决方案三

验证headers属性是否书写规范!

axios({
    method:"post",
    url:"http://127.0.0.1/sum",
    data:{
        a:1,
        b:2
    },
    headers:{
        "Content-Type":"application/json"
    },
    transformRequest(data,headers) {
        let normalizedName = "Content-Type";
        for(var key in headers){
            if(key != normalizedName &&  key.toLowerCase() === normalizedName.toLowerCase()){
                headers[normalizedName] = headers[key];
                delete headers[key];
                break;
            }
        }
        return JSON.stringify(data);
    }
}).then(data => {
    console.log(data);
})
五、小结
这其实是一个书写上的弱智错误,之所以会放在本文中,是因为很多程序员的职业生涯中都有过类似的写!错!经历!main和mian傻傻看不出来!
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP