经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
vue?cli3?项目中如何使用axios发送post请求
来源:jb51  时间:2022/4/7 10:49:16  对本文有异议

使用axios发送post请求

react  同样适用

首先需要安装对应的第三方包

  • cnpm  i  -S axios
  • cnpm  i  -S lodash

然后在做下边的

在vue 项目中创建一个这样的文件目录

发送post请求 

index.js中的文件内容是:

  1. import axios from "axios"
  2. import _ from "lodash"
  3. // 处理请求参数
  4. const coverFormData = (obj) => {
  5. let data = Object.keys(obj.data).map(item => {
  6. let value = obj.data[item];
  7. if(_.isArray(value) || _.isObject(value)){
  8. value = JSON.stringify(value)
  9. }
  10. return encodeURIComponent(item) + '=' + encodeURIComponent(value);
  11. }).join('&');
  12. return {data: data, url: obj.url};
  13. }
  14. function post(obj) {
  15. const { data, url } = coverFormData(obj);
  16. return new Promise((resolve, reject) => {
  17. axios.post(url, data)
  18. .then(res => {
  19. // obj.success ? obj.success(res) : null
  20. resolve(res.data);
  21. })
  22. .catch(error => {
  23. // obj.error ? obj.error(error) : null;
  24. reject(error);
  25. })
  26. })
  27. }
  28. let requests = {}
  29. requests.post = post
  30. export default requests

使用:

 效果:

发送get请求将index.js中再添加如下代码

  1. requests.get = obj => {
  2. const { data, url } = coverFormData(obj);
  3. return new Promise((resolve, reject) => {
  4. axios.get(url + '?' + data).then(res => {
  5. obj.success ? obj.success(res) : null;
  6. resolve(res.data);
  7. }).catch(error => {
  8. obj.error ? obj.error(error) : null;
  9. reject(error);
  10. })
  11. })
  12. }

使用和post的一模一样只是将requests.post改成request.get

vue使用axios的踩坑记录

axios跨域

在自己写的一个项目中,想要直接将学号和密码发到学校的教务系统,结果跨域了。。。。。。

原代码

  1. // url为要访问的域名
  2. axios.get(`${url}?method=authUser&xh=${this.sNo}&pwd=${this.password}`)
  3. .then((res) => {
  4. // ...
  5. }).catch((err) => {
  6. // ...
  7. })

在这里插入图片描述

在网上找解决跨域的问题时,看到很多都是修改config下的…文件,但是vue-cli脚手架创建的vue3项目中并没有config文件夹,所以直接去到官方文档查找配置

解决方法

在package.json同级文件夹下创建vue.config.js,配置如下

  1. module.exports = {
  2. devServer: {
  3. proxy: {
  4. '/api': {
  5. target: 'url', //设置要访问的域名和端口号
  6. changeOrigin: true, //设置为跨域
  7. pathRewrite: {
  8. '^/api': '/' //这里理解成用‘/api'代替target里面的地址,在后面发起请求时,/api就会代替target中的值,可以实现跨域
  9. }
  10. }
  11. }
  12. }
  13. }

修改我们的请求代码

  1. axios.get(`/api/app.do?method=authUser&xh=${this.sNo}&pwd=${this.password}`)
  2. .then((res) => {
  3. // ...
  4. }).catch((err) => {
  5. // ...
  6. })

这里使用/api替换了原来的url,实现跨域

axios发起post请求后端无法接收数据

在第一次使用axios向后台发送post请求时,发现自己发送的数据后端没有接收到,后端用的是spring框架,但是同样的请求我使用自己的node服务器测试时却好好的

原代码

  1. axios.post(url,{data:data})
  2. .then(res => {
  3. // ...
  4. }).catch(err => {
  5. // ...
  6. })

我用node服务器打印请求发过拉的数据,都能得到{"data":1},但是后端那里总是只能得到null

在查看前后端代码后总是觉得没问题,唯一的变数只有axios了,所以去到淘宝镜像上看axios的使用,看到特性里面的概述

在这里插入图片描述

大概就是说可以对请求中的数据和响应的数据做格式转换,而且会自动对json数据做转换,我尝试将上面的请求改成使用非json格式传输

  1. axios.post(url,`data=${data}`)
  2. .then(res => {
  3. // ...
  4. }).catch(err => {
  5. // ...
  6. })

意料之中的成功了,那么为什么呢,在查阅资料后,终于在GitHub上找到了对应的源码

  1. transformRequest: [function transformRequest(data, headers) {
  2. normalizeHeaderName(headers, 'Accept');
  3. normalizeHeaderName(headers, 'Content-Type');
  4. if (utils.isFormData(data) ||
  5. utils.isArrayBuffer(data) ||
  6. utils.isBuffer(data) ||
  7. utils.isStream(data) ||
  8. utils.isFile(data) ||
  9. utils.isBlob(data)
  10. ) {
  11. return data;
  12. }
  13. if (utils.isArrayBufferView(data)) {
  14. return data.buffer;
  15. }
  16. if (utils.isURLSearchParams(data)) {
  17. setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
  18. return data.toString();
  19. }
  20. // 看这里------------------------------------------
  21. if (utils.isObject(data)) {
  22. setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
  23. return JSON.stringify(data);
  24. }
  25. return data;
  26. }]

当判断为对象时,会把headers设置为application/json;charset=utf-8,也就是Content-Type,而根据项目组里的后端同学所说的,服务端要求的是Content-Type': 'application/x-www-form-urlencoded,我试着在发送请求前将headers设置为application/x-www-form-urlencoded,结果还是不行,大概是因为源码中对headers的修改在自己的设置之后实现的,但是这样写的话,要写出一串很长的字符串,感觉挺麻烦的,那就可以尝试下面的方法

因为源码中是通过transformRequest来修改headers的,而这个方法我们其实也可以自己实现,所以我们只要在发送请求的时候自己来实现这个方法就可以了,这里通过修改data的数据结构来达到目的

  1. import Qs from 'qs'
  2. axios({
  3. url:url,
  4. data:{
  5. data:data
  6. },
  7. transformRequest: [function (data) {
  8. // 对data的数据格式进行修改
  9. return Qs.stringify(data)
  10. }],
  11. headers: {
  12. 'deviceCode': 'A95ZEF1-47B5-AC90BF3'
  13. })
  14. .then(res => {
  15. // ...
  16. }).catch(err => {
  17. // ...
  18. })

上面是将data的数据格式进行转换,但是我们也可以选择修改处理data的方式

  1. axios({
  2. url:url,
  3. data:{
  4. data:data
  5. },
  6. transformRequest: [function transformRequest(data, headers) {
  7. normalizeHeaderName(headers, 'Accept');
  8. normalizeHeaderName(headers, 'Content-Type');
  9. if (utils.isFormData(data) ||
  10. utils.isArrayBuffer(data) ||
  11. utils.isBuffer(data) ||
  12. utils.isStream(data) ||
  13. utils.isFile(data) ||
  14. utils.isBlob(data)
  15. ) {
  16. return data;
  17. }
  18. if (utils.isArrayBufferView(data)) {
  19. return data.buffer;
  20. }
  21. if (utils.isURLSearchParams(data)) {
  22. setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
  23. return data.toString();
  24. }
  25. // 看这里------------------------------------------
  26. if (utils.isObject(data)) {
  27. setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
  28. let _data = Object.keys(data)
  29. return encodeURI(_data.map(name => `${name}=${data[name]}`).join('&'));
  30. }
  31. return data;
  32. }])
  33. .then(res => {
  34. // ...
  35. }).catch(err => {
  36. // ...
  37. })

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号