应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

vue使用axios调用接口,解决跨域。vue调用api接口。vue请求封装

21369人阅读 2020/7/8 11:36 总访问:5182763 评论:12 收藏:0 手机
分类: 前端

一.先下载axios依赖

  1. npm install axios


二.在需要的地方引入

  1. import axios from 'axios'



三.环境准备好了之后就可以使用axios调用接口了

简单语法:
axios.get("url",{参数}).then(function(response){

});

例子:



四.解决跨域

如果直接这样调用是会存在跨域的


在webpack.config.js中的devServer去配置跨域。或者是vue.config.js,或者config文件夹下的index.js文件中配置。版本不同配置文件会不一样,比如:vue-cli2.0时代,webpack的配置文件写在config/index.js 文件,vue-cli3.0时代,没了config文件夹,vue.config.js写在项目的根目录下

  1.   devServer: {
  2.     historyApiFallback: true,
  3.     noInfo: true,
  4.     proxy: {
  5.       '/api': {
  6.         changeOrigin: true,
  7.         target: 'http://m.tnblog.net/api/v1/home/1'
  8.       },
  9.       '/myapi': {
  10.         changeOrigin: true,
  11.         target: 'http://localhost:7324'
  12.       }
  13.     }
  14.   },

try again在调用试试,这样配置后我们就可以使用/myapi,来替代http://localhost:7324这个地址了。

  1. axios.get("/myapi/api/dept/6").then(function(response){
  2.     console.log(response);
  3. });

还是不行会报404的错误


我们在去配置一个pathRewrite,也就是路径重写,就可以解决这个404的问题了

  1. '/myapi': {
  2.   //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求
  3.   changeOrigin: true,
  4.   target'http://localhost:7324',
  5.   pathRewrite:{
  6.     '^/myapi':''
  7.   }
  8. }

可以看到已经得到结果了


特别注意:修改了配置文件后,把vue服务停止了在重启一下,不然是没有效果的。他这个跨域的解决方法其实就是中间加了一层代理而已



五.全局引用axios

上面的引用方式在需要的地方引用,每次都要引用就会很麻烦,我们可以在main中全局引用一下,其他地方都可以用了

  1. import axios from 'axios'
  2. //全局引用axios
  3. Vue.prototype.$http = axios




然后使用的时候就可以用vue的对象直接点$http出来使用了,这个名字是可以随便取得


例如:


写完收工....准备吃饭


六.请求封装

请求封装可以统一处理一些事情,比如统一的loading处理,统一的token处理,统一请求拦截等。


先在src目录中创建一个common文件夹,然后创建一个request.js文件

先进行一点很简单的封装

  1. import axios from 'axios'
  2. import qs from 'qs'
  3. const request = {
  4.     get(url, data,_success)
  5.     {
  6.         // 判断有没有参数,有参数就把参数加上
  7.         if(data)
  8.         {
  9.             url = url+ '?' + qs.stringify(data)
  10.         }
  11.         console.log(url)
  12.         axios.get(url).then(function (response{
  13.             _success(response)
  14.         });
  15.     },
  16.     post(url, data,_success)
  17.     {
  18.         axios.post(url,data).then(function (response{
  19.             _success(response)
  20.         });
  21.     }
  22. }
  23. export default request

这里还用到了一点qs做序列化用,需要先安装一下,npm install qs。



然后在main.js中去进去全局引用

  1. import request from './common/request.js'
  2. Vue.prototype.$http = request


然后就可以在需要的页面使用了
发送一个get请求

  1. this.$http.get("/api/v1/Home/1",null,function(response){
  2.     console.log(response)
  3. })

发送一个post请求

  1. this.$http.post("/api/v1/Home",{userName:"张三"},function(response){
  2.     console.log(response)
  3. })


使用Promise封装一下请求,就可以不用传递回调函数了

  1. import axios from "axios";
  2. import qs from "qs";
  3. const request = {
  4.   get(url, data) {
  5.     // 判断有没有参数,有参数就把参数加上
  6.     if (data) {
  7.       url = url + "?" + qs.stringify(data);
  8.     }
  9.     return new Promise((resolve, reject) => {
  10.         axios.get(url).then(function (response{
  11.             resolve(response);
  12.         })
  13.         .catch((e) => {
  14.           reject(e);
  15.         });
  16.     });
  17.   },
  18.   post(url, data) {
  19.     return new Promise((resolve, reject) => {
  20.         axios.post(url, data).then(function (response{
  21.             resolve(response);
  22.         })
  23.         .catch((e) => {
  24.             reject(e);
  25.         });
  26.     });
  27.   },
  28. };
  29. export default request;

现在调用的时候就不需要传递回调函数了,直接使用then方法即可。

  1. this.$http.get("/api/v1/Home/1"null).then((res)=>{
  2.     console.log("数据成功回来了")
  3.     console.log(res)
  4. })
  5. this.$http.post("/api/v1/Home", { userName"张三" }).then((res)=>{
  6.     console.log("post数据成功回来了")
  7.     console.log(res)
  8. })



Promise的使用可以参考:https://www.tnblog.net/xiuxin/article/details/8147


然后可以进行一点返回状态判断status为200才是请求成功
封装如下:

  1. return new Promise((resolve, reject) => {
  2.     axios.get(url).then(function (response{
  3.         //判断一下请求状态
  4.         if (response.status === 200){
  5.             resolve(response);
  6.         }
  7.         else
  8.         {
  9.             reject(response);
  10.         }
  11.     })
  12.     .catch((e) => {
  13.         reject(e);
  14.     });
  15. });

还可以和自己后台接口规定的状态一起进行判断,比如我们后台接口规定正确状态的返回为200,我们就可以这样判断。返回的值也可以直接取data之后的了。(tip:这个判断要根据你的实际情况修改判断对哦,不然使用else里边的reject输出,虽然结果也能正确输出,但是浏览器上会提示Uncaught (in promise)),也不能继续正确的向下执行了)。


统一请求拦截
代码如下:

  1. // 请求拦截器
  2. axios.interceptors.request.use((axiosconfig) => {
  3.     console.log("进入请求拦截器了")
  4.     console.log(axiosconfig)
  5.     return axiosconfig;
  6.   },
  7.   (err) => {
  8.     return Promise.reject(err);
  9.   }
  10. );

比如可以做统一的登录验证,统一设置header bearer token,统一请求地址处理等。

  1. // 请求拦截器
  2. axios.interceptors.request.use(axiosconfig => {
  3.     // loading.open() // 打开加载窗口
  4.     // 统一访问登录信息。方法内部可以去写如果没有登录就跳转到登录页等逻辑
  5.     var loginfo = utils.getloginfo()
  6.     if (loginfo && loginfo.token) {
  7.       axiosconfig.headers.Authorization = 'Bearer ' + loginfo.token // 统一的token处理
  8.     }
  9.     else{
  10.      // token没有获取到就跳转到登录页,跳转的地址不要接域名本地开发环境就跳转到开发环境,线上就自动跳转到线上
  11.      location.href = "/#/login?redirect=/school-dashboard#/index";
  12.     }
  13.     
  14.     // 统一请求地址处理。统一增加一个前缀
  15.     axiosconfig.url = config.serverhost + axiosconfig.url
  16.     return axiosconfig
  17.   },
  18.   err => {
  19.     //loading.close() // 关闭加载窗口
  20.     return Promise.reject(err)
  21.   }
  22. )




这类统一的处理其实就很类似后台的过滤器,中间件这类的东西,可以统一的实现一些逻辑。


统一响应拦截
代码如下:

  1. // 响应拦截器
  2. axios.interceptors.response.use((response) => {
  3.     console.log("统一响应了")
  4.     return response;
  5.   },
  6.   (err) => {
  7.     return Promise.reject(err);
  8.   }
  9. );

你要进行什么统一响应的处理写到这里即可,比如统一的错误提示,统一的后台接口状态码处理,统一的token错误过期处理等,就不用写到每个请求封装里边了。

还可以进行统一的超时时间设置,或者是请求格式设置等

  1. axios.defaults.timeout = 300000 // 设置超时时间
  2. // 配置请求头数据格式
  3. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'


还可以不直接使用默认的axios对象,而且是创建一个新的

比如:下面的代码就是创建了一个新的axios对象,并且统一设置了baseURL以及超时时间,baseURL从环境变量里边读取的,就可以做到比如线下开发环境请求接口的时候需要加上一个前端,发布后就不需要前缀了

  1. // create an axios instance
  2. const service = axios.create({
  3.   baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  4.   // withCredentials: true, // send cookies when cross-domain requests
  5.   timeout: 60000 // request timeout
  6.   // maxContentLength: Infinity // 客户端不限制大小
  7. })

创建了一个新的对象后,封装的代码就不直接使用axios对象了,而是使用刚刚创建的service对象,例如统一的请求拦截处理

  1. service.interceptors.request.use(
  2.   config => {
  3.     //  If-Modified-Since:0 IE浏览器缓存强制过期A
  4.     config.headers['If-Modified-Since'] = 0
  5.     // 用于权限菜单用
  6.     config.headers['m-id'] = router?.app?._route?.meta?.id ?? 0
  7.     // do something before request is sent
  8.     if (store.getters.token) {
  9.       // let each request carry token
  10.       // ['X-Token'] is a custom headers key
  11.       // please modify it according to the actual situation
  12.       config.headers['Authorization'] = 'Bearer ' + getToken()
  13.     }
  14.     return config
  15.   },
  16.   error => {
  17.     // do something with request error
  18.     console.log(error) // for debug
  19.     return Promise.reject(error)
  20.   }
  21. )




贴一个目前稍微完整一点的

  1. import axios from "axios";
  2. import qs from "qs";
  3. axios.defaults.timeout = 300000 // 设置超时时间
  4. // 配置请求头数据格式
  5. // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
  6. // 请求拦截器
  7. axios.interceptors.request.use((axiosconfig) => {
  8.     console.log("进入请求拦截器了")
  9.     console.log(axiosconfig)
  10.     return axiosconfig;
  11.   },
  12.   (err) => {
  13.     return Promise.reject(err);
  14.   }
  15. );
  16. // 响应拦截器
  17. axios.interceptors.response.use(
  18.   (response) => {
  19.     console.log("统一响应了");
  20.     return response;
  21.   },
  22.   (err) => {
  23.     return Promise.reject(err);
  24.   }
  25. );
  26. const request = {
  27.   get(url, data) {
  28.     // 判断有没有参数,有参数就把参数加上
  29.     if (data) {
  30.       url = url + "?" + qs.stringify(data);
  31.     }
  32.     return new Promise((resolve, reject) => {
  33.       axios.get(url).then(function (response{
  34.           console.log("封装的方法数据回来了");
  35.           if (response.status === 200 && response.data.code === 200) {
  36.             resolve(response.data);
  37.           } else {
  38.             reject(response.data);
  39.           }
  40.         })
  41.         .catch((e) => {
  42.           reject(e);
  43.         });
  44.     });
  45.   },
  46.   post(url, data) {
  47.     return new Promise((resolve, reject) => {
  48.       axios.post(url, data).then(function (response{
  49.           if (response.status === 200) {
  50.             resolve(response);
  51.           } else {
  52.             reject(response);
  53.           }
  54.         })
  55.         .catch((e) => {
  56.           reject(e);
  57.         });
  58.     });
  59.   },
  60. };
  61. export default request;


增加一个统一的请求loading效果
例如使用element ui的laoding。

先引入element ui中loading组件

  1. import {Loading} from 'element-ui'
  2. const loading = { // loading加载对象
  3.   loadingInstance: null,
  4.   // 打开加载
  5.   open(loadtext) {
  6.     if (this.loadingInstance === null) { // 如果实例 为空,则创建
  7.       this.loadingInstance = Loading.service({
  8.         text: loadtext, // '加载中...', // 加载图标下的文字
  9.         spinner: 'el-icon-loading'// 加载图标
  10.         background: 'rgba(0, 0, 0, 0.8)'// 背景色
  11.         customClass: 'loading' // 自定义样式的类名
  12.       })
  13.     }
  14.   },
  15.   // 关闭加载
  16.   close() {
  17.     // 不为空时, 则关闭加载窗口
  18.     if (this.loadingInstance !== null) {
  19.       this.loadingInstance.close()
  20.     }
  21.     this.loadingInstance = null
  22.   }
  23. }

然后在请求拦截中去打开,在结束拦截中去关闭以及错误的情况去关闭即可

  1. // 请求拦截器
  2. axios.interceptors.request.use((axiosconfig) => {
  3.     loading.open()
  4.     console.log("进入请求拦截器了")
  5.     console.log(axiosconfig)
  6.     return axiosconfig;
  7.   },
  8.   (err) => {
  9.     loading.close() // 关闭加载窗口
  10.     return Promise.reject(err);
  11.   }
  12. );
  13. // 响应拦截器
  14. axios.interceptors.response.use(
  15.   (response) => {
  16.     console.log("统一响应了");
  17.     loading.close() // 关闭加载窗口
  18.     return response;
  19.   },
  20.   (err) => {
  21.     loading.close() // 关闭加载窗口
  22.     return Promise.reject(err);
  23.   }
  24. );
  25. const request = {
  26.   get(url, data) {
  27.     // 判断有没有参数,有参数就把参数加上
  28.     if (data) {
  29.       url = url + "?" + qs.stringify(data);
  30.     }
  31.     return new Promise((resolve, reject) => {
  32.       axios.get(url).then(function (response{
  33.           console.log("封装的方法数据回来了");
  34.           if (response.status === 200 && response.data.code === 200) {
  35.             resolve(response.data);
  36.           } else {
  37.             reject(response.data);
  38.           }
  39.         })
  40.         .catch((e) => {
  41.           reject(e);
  42.         });
  43.     });
  44.   },
  45.   post(url, data) {
  46.     return new Promise((resolve, reject) => {
  47.       axios.post(url, data).then(function (response{
  48.           if (response.status === 200) {
  49.             resolve(response);
  50.           } else {
  51.             reject(response);
  52.           }
  53.         })
  54.         .catch((e) => {
  55.           reject(e);
  56.         });
  57.     });
  58.   },
  59. };
  60. export default request;


如果想某些接口调用不用laoding效果,就可以这样实现

在请求拦截的时候不去开启loading,不然每个请求都会打开loading,而是给一个参数,有的情况才开启

  1. post(url, data, loadtext) {
  2.   if (loadtext && loadtext.length > 0) {
  3.     loading.open(loadtext); // 加载Loading
  4.   }
  5.   return new Promise((resolve, reject) => {
  6.     axios.post(url, data).then(function (response{
  7.         if (response.status === 200) {
  8.           resolve(response);
  9.         } else {
  10.           reject(response);
  11.         }
  12.       })
  13.       .catch((e) => {
  14.         reject(e);
  15.       });
  16.   });
  17. },

上面就判断了如果有传递loadtext就执行open方法打开loading,调用接口的时候如果需要loading就传递一个字符串过来就行

  1. this.$http.post("/api/v1/Home", { userName"张三" },"数据请求中").then((res) => {
  2.     console.log("post数据成功回来了")
  3.     console.log(res)
  4. })

当然还有很多可以封装,根据实际的业务情况进行封装就行了

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

饰心

2020/7/8 12:54:41

跨域不是后端来处理嘛:app.UseCors();

剑轩:@饰心[托腮].....有些接口的后端我们控制不了哇

2020/7/8 14:53:19 回复

人生若只如初见

2020/7/8 15:52:55

跨域还可以使用qs啊

剑轩:@人生若只如初见这个只是一个序列化的库哇,前后台约定好格式就行了

2020/7/8 16:11:50 回复

人生若只如初见

2020/7/8 15:54:27

而且,用了好久发现vue使用 ajxa  要好些  自动解决跨域就是core 后台接收的时候  如果是post 就要 fromfrom 这个特性了

剑轩:@人生若只如初见ajax?jquery的ajax?axios也是发送的异步请求哇

2020/7/8 16:13:48 回复

人生若只如初见:@剑轩嗯,有时候感觉不好用,或者是我没弄好

2020/7/8 17:32:21 回复

剑轩:@人生若只如初见嗦嘎,确实也是有坑

2020/7/8 17:34:58 回复

是伍尚金哇_v

2020/7/9 14:31:20

前端整跨域用的代理(后端不处理得话)

剑轩:@是伍尚金哇_v不处理的话会怎样?

2020/7/9 15:03:01 回复

是伍尚金哇_v:@剑轩后端不处理 就前端可以代理来处理啊

2020/7/10 12:33:31 回复

剑轩:@是伍尚金哇_v嗦嘎,是的,就是这样~

2020/7/10 14:40:23 回复

vue.js+Layer实现表格数据绑定与更新

一:使用Vue.js绑定好数据与更新事件 使用v-on绑定好事件,在事件里边直接把该行数据传递进去,在更新方法里边就可以直接...

vue.js 实现省市联动

HTML代码<divid="pro_citys"> 省:<selectid="provice"v-on:change="prochange()&quo...

vue.js常见问题

一:花括号当做字符串显示的问题1:检查下绑定到vue.js的id是否重复,如果id重复了,就有可能存在这种问题,因为有可能把数...

vue.js常用指令

v-html可以把字符串当成一个html来渲染,而不是原样输出Html类似.net mvc中的@Html.Raw()方法<divv-html="item.tit...

干货!div滚动到一定位置就固定他。vue中实现一侧滚动到底部就固定

尊重原创:转载请注名出处div滚动到一定位置就固定他,例如左边的内容很多,右边的内容很少,如果不处理滚动到一定位置后右...

vue.js常用指令事件绑定等vue过滤器解析状态过滤器多个参数。vue表格状态解析。vue解析类型element ui解析类型状态el-tag

按照html的编码显示:v-html<div class="font_info" v-html="item.Content">{{item.Content}}&l...

vue.js if用法

vue.js if可以做一些判断例如我们要把下面这个输出varvm=newVue({ el:"#content", data:{ titles:["小明...

vue.js 学习日记第一章-安装vue开发环境

官网:https://cn.vuejs.org/v2/guide/ 这是一篇学习性文章,不定时更新,用来记录我学习vue.js的过程。 首先,是v...

vue.js 学习日记第二章-在vue中编写function及一些简单指令

官网:https://cn.vuejs.org/v2/guide/ vue.js 学习日记第一章:http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第三章-vue中的简单事件及事件修饰符

官网:https://cn.vuejs.org/v2/guide/ vue.js 学习日记第二章:http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第四章-vue中文本框数据获取与绑定及computed计算属性

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第三章: http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第五章-v-if和v-for指令的使用方式

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第四章: http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第六章-vue组件初步学习

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第五章: http://www.tnblog.net/18323015640/article/details/2...

vue.js学习日记第七章-搭建脚手架

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第六章: http://www.tnblog.net/18323015640/article/details/2...

vue实现好友选中效果

逛过vue官网肯定会发现一个有趣的指令“v-for”,相比与以前拼接html代码确实要上档次一点,而且减少了工作量,先看一波效...

js时间格式化vue.js时间格式化带T 时间格式化

也可以借助moment库, 参考:https://www.tnblog.net/aojiancc2/article/details/8079moment库有点大,推荐可以使用day.js...