世界就像一个巨大的图书馆,我们读着别人,做着自己,等待被读。 :

前端框架Vue自学之axios(九)

我的最新博客在:Secret_wu's coding note

终极目标:掌握和使用Vue(全家桶:Core+Vue-router+Vuex)

本博客目的:记录Vue学习的进度和心得(axios)

内容:学习和使用axios,网络模块封装。

正文:

axios

一、网络模块封装

  1、网络请求

  Vue中发送网络请求有非常多的方式,那么,在开发中,如何选择?

  选择一:传统的Ajax是基于XMLHttpRequest(XHR)。一般不用,因为配置和调用方式等非常混乱。所以真实开发中很少直接使用,而是使用jQuery-Ajax。

  选择二:jQuery-Ajax。相对于传统的Ajax,其有优势。但是也不选择它,因为Vue的整个开发中都是不需要使用jQuery。完全没有必要为了用网络请求就引用这个重量级的框架。

  选择三:官网vue1.x的时候,推出了Vue-resource插件。Vue-resource的体积相对于jQuery小很多,并且是官网的。但也不选,Vue2.0推出后,作者不在更新。使用这个对以后的项目开发和维护存在很大的隐患。

  选择四:axios。vue作者说明不在继续更新和维护Vue-resource插件,但推荐了一个框架:axios。它有很多优点,并且用起来很方便。

  2、jsonp

  在前端开发中,我们一种常见的网络请求方式就是JSONP。使用JSONP最主要的原因往往就是为了解决跨域访问的问题。

  JSONP的原理是:

   但我们这里还是重点研究axios

二、axios

  1、axios的功能特点

  axios:ajax i/o system(一个老师理解的翻译,网上也没找到具体指的是什么)。

  在浏览器中发送XMLHttpRequests请求;在node.js中发送HTTP请求;支持Promise API;拦截请求和响应;转换请求和响应数据等等。

  2、axios支持多种请求方式

  axios支持多种请求方式,和http请求有关,例如request,post,get,put等。

  

   3、在vue下的axios的简单使用

  首先创建vue项目,这里为了更好看到目录结构,我们使用Vue CLI2安装,终端输入vue init webpack learnaxios,然后选择默认和不安装vue-router等插件(具体步骤可以看我之前关于Vue CLI的博客)。(接着把一些我们不用的代码删掉,如HelloWorld.vue相关的东西)

  现在假设我们在App.vue里面发送一个网络请求,从服务器请求过来一个数据,然后对数据进行展示。

   首先,安装axios。npm install axios --save(运行是依赖)

  然后,导入使用。在任意文件都可以使用axios。为了演示,我们在main.js中使用axios,以axios(config)的方式。axios是支持Promise的。url只是

   

   这个url是对应服务器端口路径的数据,即后端接口:http://123.207.32.32:8000/home/multidata

   之后运行代码,在控制台就打印这个网络请求的数据(从服务器端来的数据)。其是一个对象,里面包含数据,配置,请求方式,状态等信息。但注意,这些信息(除了data数据)都是axios框架加上的,不是在服务器端写返回的。

  

  axios参数中,只使用url的默认请求方式是get请求。我们可以使用method,来设置请求方式,如post。当然也可以使用axios.post()的形式。

  (这个服务器接口是不支持post方式请求的,只是演示而已) 

  此外,httpbin.org可以对网站进行很多的模拟,用于测试等。

  如果我们想使用query的网络请求,除了可以直接以get方式请求完整接口,也可以使用params。

三、axios发送并发请求

  我们想做发送两个并发的请求,并且要等两个请求都到达后,才能做相应处理的需求。之前我们是使用Promise.all来解决的。这里我们使用axios框架。

  使用axios.all()对多个网络请求进行合并,参数是传入数组,里面放置请求,如请求1和请求2。然后在最后用.then()函数拿到最终结果。

  (基本格式示意)

  例如我们把第二章的两个请求当做并发请求。

  

   最后结构是一样的。结果是一个数组。

  

   如果我们想把数组展开,使用axios.spread可以将数组[res1,res2]展开为res1, res2。

   

四、axios的配置信息相关

  1、全局配置

  在上面一些例子中,我们的BaseURL是固定的。事实上,在开发中可能很多参数都是固定的(例如一些headers请求)。

  

  这个时候我们可以进行一些抽取,也可以利用axios的全局配置。  

  利用axios.defaults可以对一些属性进行全局配置,例如baseURL。

  

   2、常见的配置选项

五、axios的实例和模块封装

  1、axios的实例  

  为什么要创建axios的实例?

  当我们从axios模块中导入对象时,使用的实例是默认的实例。当给该实例设置一些默认配置时,这些配置就被固定下来了。但后续开发中,某些配置可能会不太一样,比如某些请求需要使用特定的baseURL或者timeout或者content-Type等。这个时候(使用上述的参数的全局配置就不合适),我们就可以创建新的实例,并且传入属于该实例的配置信息。

  当项目越来越大的时候,服务器接口不一定是一个端,它可能是把服务器发到多个端。通过nginx部署服务器,做反向代理。服务器分布式,当服务器在部署的时候,当并发量很大的时候,一个服务器是无法满足业务需求,所以一般需要多个服务器(每个服务器一个ip地址),但是客户端需要知道哪里请求对应哪里服务器(ip地址),就很麻烦。所以nginx相当于部署一个代理服务器,当客户端发送请求时,指向都是这个代理服务器,先经过代理服务器,然后代理服务器通过判断哪个服务器是比较空闲合适的,在把请求发到对应服务器。

  2、创建对应的axios的实例

  axios.create(config)创建这个config的实例。

  

   还可以正常拿到结果。

  当我们还有别的请求,可以类似地创建instance2等,设置单独的baseURL,timeout等。

  3、模块封装

  之前我们写的axios代码都是在main.js中写的(为了演示),真实开发中,我们需要网络请求模块封装。

   方式一:我们可以在需要使用到axios的组件中导入axios,然后用create()周期钩子使用axios,并输出结果,把结果用data保存,并展示到对应地方。

 

   但这种方式导致,我们要用到axios的组件都必须导入axios,然后进行配置和使用,这样组件对第三方框架依赖太强了。这样维护会麻烦。

  补充:真实开发中,只要引入第三方的东西,千万不要在每个组件都对这个第三方东西依赖,一旦第三方的东西不能用了(如不更新和维护了),那么意味着对应每个组件都需修改。所以我们必须对第三方的东西进行封装,让其面向我们的组件。这样维护只需修改封装的文件即可。

  方式二:所以我们对axios进行封装。

  首先,在src下创建network文件夹。network文件夹下创建request.js。如果我们是要导入多个实例的话,写成export function XX的形式(而不是export default形式)。注意上一节说过不要创建全局配置,而是使用axios配置。

  然后发送出真正的网络请求。通过传入success函数和failure函数导出网络请求结果。

  

   然后在main.js中,导入request模块,使用request,把config配置和sucees,failure函数对应写好。

  

   最后结果还是可以网络请求得到。

  

   但这不是我们的最终方案。

  方式三:我们的最终方案是用Promise。(但方式四才是最终版本)

  request.js使用Promise。

  

   main.js使用的request时使用then(),catch()

  

   一样可以请求出正常的结果。

  方式四:简化方式三。

  因为由axios.create()创建的axios实例本身就是一个Promise(源码体现出的)。所以直接返回实例即可。

  

   使用request和方式三一致。显示的请求结果也是正常的。

  优点:由于我们把axios封装到一个文件内,并且使用Promise导出网络请求的结果。所以如果某一天axios不在更新和维护,我们可以直接修改这个文件,也写成使用Promise导出网络请求的方式,其他使用这个网络请求的组件文件也不需要修改了。(这才是封装啊)

六、axios拦截器的使用

  1、axios拦截器

  axios提供了拦截器,用于我们在发送每次请求或者得到响应后,进行对应的处理。如url拼接等。axios提供了4种拦截器:请求成功的拦截和请求失败的拦截,响应成功的拦截和响应失败的拦截。(客户端请求,服务端响应

  具体怎么使用呢?(注意,拦截也要返回结果,后面会说)

  全局拦截:axios.interceptors 。但通常我们使用的是实例拦截。

  实例拦截:(instance.interceptors.request.use请求拦截,instance.interceptors.response.use响应拦截)

  请求拦截,instance.interceptors.request.use里面有两个参数(看源码),一个是拦截成功的函数,一个是拦截失败的函数。

 (源码)

   

   此时,拦截了请求,在控制台打印了结果,但是报了一个错误。是由于请求被拦截了,如果没有使用reture把请求结果返回,则出错误信息。

  

   所以,使用拦截器的时候记得加上reture把结果返回。

  

   此时就没有报错了。

  

  2、请求情况分析

  现在,我们是拦截了请求,我可以做一些操作。通常情况有:

  情况一:config中的一些信息不符合服务器要求,需要某些操作。例如修改特殊的header。

  情况二:每次发生网络请求时,都希望在界面中显示一个请求的图标。例如一个转圈表示等待的图标。相当于正在请求时,显示图标,请求结束后,图标消失,显示页面的效果。

  情况三:某些网络请求(比如登录(token)),必须携带一些特殊的信息。首先拿到一个url,看是否是些特殊请求,在这请求中有没有传入token信息,可以判断用户有没有登录,如有token,则可以让其继续发送请求;如果没有,给一些错误提示,让其登录,再进行访问。

  3、响应拦截

  instance.interceptors.response.use 响应拦截,也有有两个参数。第一个是结果。由于服务器响应过了,这里拿到的是结构。第二个是失败的情况。

  

   结果显示。

  

   当我们(人为)让请求失败,例如给个错误的url。则正常输出错误结果。

  

  一样地,当我们拦截后,必须返回结果,不然请求的东西是会报错的。

   

  通常返回的是data。(其他信息是axios框架后面添加的,有时候我们只需要data)

  

  

posted @ 2019-12-30 16:55  Secret_Wu  阅读(426)  评论(0编辑  收藏  举报