关乎vue的axios问题
最初用axios作为一个post发送,发送代码如下:
axiosN
.post(path,data)
.then(response => {
console.log(response.data)
this.dialogFormVisible = false
this.$notify({
title: "提示",
message: response.data.msg,
type: response.data.type,
duration: 2000
})
})
.catch(function (error) {
console.log(error);
return 0
});
后端采用flask作为接收,代码如下:

浏览器的开发者工具显示


一切都看似正常,浏览器显示有提交数据data,也显示和后端进行了交互返回数据
后来,,项目对接给后端时,变样了,后端显示没有收到数据
也就是提交数据data,其他url都正常,唯独没有data
CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([])])
很明显,这是后端输出的request.values,正常情况下应该是这样
CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([('{"page":1,"limit":20,"Dtoken":"admin-token"}', '')])])
那么从浏览器的开发者工具来看

并且

这些都指向一个事情,问题应该是在后端那边
但是后面来看,事情没有那么简单,反而是前端出了问题,ok
首先祭出post模拟器

后端响应:
CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([('{"page":1,"limit":20,"Dtoken":"admin-token"}', '')])])
127.0.0.1 - - [01/Mar/2021 21:24:53] "?[37mPOST /getResultList HTTP/1.1?[0m" 200 -
这时候说明后端没有问题,而是前端,但是仔细分析,浏览器的开发者工具显示了提交的表单,而且也正常有return啊,这时候就非常矛盾了
为了验证到底是不是flask的问题,我用其他语言写了个本地web服务器,但是同样,使用模拟器发送都正常,唯独用axios发送就出现问题了
那现在定位基本锁定是在前端了,前端的交互其实是跨域交互,那么这个跨域也使得问题变得复杂化(跨域指跨域名,跨ip,跨端口)
那问题出现了,其实很简单,就是百度
网上提出了几种方案,总结来看:


使用结果:还是一样
CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([])])
这时候很头疼了,那项目又急,我最开始为了应付一下,解决方案如下:
既然post无法让后端接收到数据,而url接收是没问题的,那我就使用上面的
qs.stringify({})
让我的表单json格式变成字符格式提交
也就是下面的注释

但是,不能用post提交,post还是接收不到
这里用的是get,也就是说,把所有post全部改成get访问,然后把它加在url后面
然后后端的flask这样

也就是用name接收,然后字符串切割
那这样,虽然能交互了
但是,也产生了以下的后果:
1.对后端的同学极其不友好,后端同学必须用字符串切割,然后拼凑信息
2.当遇到需要上传编辑器,比如需要设计样式的编辑器,那么原来表单就会出现
{"data":"<h5>测试</h5>"
当上传这种html代码时,用json完全没有问题,但是如果用qs处理,链接就会出现<>./这种数据字符,就会导致404

所以说,这种方法是治标不治本,是痛点,必须解决
OK,那我就认认真真来分析吧
最初其实我就有一个念头,感觉是协议头header出了问题
那就展开实验
前端出现跨域问题是吧,那我直接跳过跨域,也就是说,我用模拟器直接请求真实的后端地址,复制原先axios请求的所有东西,包括header
这时候,就发现后端居然也是
CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([])])
那我去掉所有协议头,只保留User-Agent,这时候,后端正常显示了

ok,那这样定位到问题了,就是在header上出了问题
那好,header存在问题,那就对之前的header进行二分法分析哪一条header出了问题
很明显,这条header引起了异常

那我把他去掉,或者说改成其他Type

这时候后端一切都正常了,那么问题的根源锁定了,就是这条header出现问题,那么解决方案就是如何让axios自定义header
翻了翻资料,发现确实,有人说也是这条出问题,axios默认header就是这种
那自定义axios header如下:
// main.js
import axios from 'axios'
import VueAxios from 'vue-axios'
axios.defaults.baseURL = 'http://127.0.0.1:5801/';
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
Vue.use(VueAxios, axios)
这里设置了跨域
那么在前端请求如下:
// 1.vue
axios
.post('/123', {
data
},
{headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
)
.then(response => {
//something
}
})
.catch(function (error) {
this.$message.error("提交异常");
console.log(error);
return 0
});
之所以这里也加,也是保险起见吧
但是现在又出现一个问题,前端的开发部分交互是指向mock
那这样,就会把所有数据完全指向了跨域的服务器,之前是设置定向交互
所以,这里引入了两个axios
import axios from '@/utils/axios'
import axiosN from 'axios'
axiosN是修改header的axios,另外一个则是和mock正常交互的axios
那么跨域交互就是
// 1.vue
axiosN
.post('/123', {
data
},
{headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
)
.then(response => {
//something
}
})
.catch(function (error) {
this.$message.error("提交异常");
console.log(error);
return 0
});
okk,that is all
在Vue应用中使用axios发送POST请求时,后端Flask无法接收到数据。经过排查,发现并非后端问题,而是前端axios的header导致的。通过模拟器测试确认问题在于特定header,移除该header后恢复正常。解决方案是自定义axios的header,以允许跨域并确保数据正确发送。同时,为处理开发与mock服务器的交互,引入了两个独立的axios实例。
901

被折叠的 条评论
为什么被折叠?



