第三十节:Vue请求:Axios请求

1. 网络请求的方式

发送网络请求的方式有很多种,到目前为止,我们已经学过了原生ajax,jquery中的ajax,等诸多网络请求的方式,那么在未来我们vue的项目中我们该如何抉择呢

先来分析一下不同的ajax请求,了解使用与否的理由

1.1 原生Ajax

原生ajax是基于XMLHttpRequest(XHR)封装的.

我们都知道原生的ajax不但有兼容问题,而且配置很调用都非常混乱, 这也是我们不使用的理由

1.2 jquery中的ajax

这个之前也提到过这类问题, jquery的ajax相对于原生的ajax来说非常好用, 但是jquery的ajax是嵌入在真个jquery中的,因此如果我们要使用jquery的ajax,就需要引入整体的jquery但是在咱们Vue项目的整个开发过程中都不需要在使用jquery,只为了用一个ajax,引入整体的jquery, 得不偿失.因此在vue中也不选用jquery 的ajax

1.3 Vue 在1.X版本是推出的Vue-resource插件

Vue-resource相较于jquery要轻量很多, 但是Vue从2.X以后就表示不再更新维护了, 如果使用它处理ajax请求,未来代码的维护上,是有很大的安全隐患的, 包括现在vue官网也不推荐你是用Vue-resource处理ajax

Vue官网推荐使用axios处理ajax

1.4 axios 请求

axios有何优点,让vue官网弃用自家的请求方式,推荐用户用axios

那么axios的优点是什么,往下看

除了以上数据请求方式外,还有包括fetch,jsonp等很多方式帮我们处理数据请求

2.axios请求了解与基本使用

2.1 axios 请求的特点
  1. 支持node端和浏览器端: 同样的API,node和浏览器全支持,平台切换无压力
  2. 支持 Promise: 使用Promise管理异步,告别传统callback方式
  3. 丰富的配置项: 支持请求和响应的拦截, 提前处理请求和响应数据
2.2 axios 使用
2.2.1 下载安装axios包
$ npm install axios

2.2.2 引入使用axios
// 引入包
import axios from "axios"

2.2.3 发送基本的请求
// 使用axios
axios({
    url:"https://api.github.com/users"
}).then(result => {
    console.log(result);
})

示例中,我们并没有请求类型, axios默认请求为get请求,

如果希望发送post等其他方式的 请求, 可以在配置对象中添加method选项

例如:

// 使用post发送请求
axios({
    url:"https://jsonplaceholder.typicode.com/posts",
    method: "post"
}).then(result => {
    console.log(result);

})

2.2.4 配置对象中指定get请求参数

我们可以像传统get请求传参一样在url路径后拼接请求数据.

例如:

axios({
  url:"https://jsonplaceholder.typicode.com/posts?userId=1",
}).then(result => {
    console.log(result);
})

也可以将get的请求数据放在axios的配置对象中

例如: 将get请求数据放在配置对象的params选项中

axios({
    url:"https://jsonplaceholder.typicode.com/posts",
    params:{
        userId: 1
    }
}).then(result => {
    console.log(result);

})

3. axios 请求方式

  1. axios(config)
  1. axios.request(config)
  1. axios.get(url[, config])
  1. axios.delete(url[, config])
  1. axios.head(url[, config])
  1. axios.options(url[, config])
  1. axios.post(url[, data[, config]])
  1. axios.put(url[, data[, config]])
  1. axios.patch(url[, data[, config]]

上面基本的示例中,我们是在axios()请求的配置对象中配置请求方式,axios也提供了通过不同的方式发送请求

指定了请求方式发送请求说明

  1. 第一个参数将是发送的url,

  2. 第二个参数是请求的配置对象,可以省略,使用默认配置

示例:

不是用配置对象

axios.get("https://jsonplaceholder.typicode.com/posts?userId=1")
  .then(result => {
     console.log(result);
  })

使用配置对象

axios.get("https://jsonplaceholder.typicode.com/posts",{
    params:{
        userId:1
    }
}).then(result => {
    console.log(result);
})

4 处理并发请求

4.1 axios.all 方法处理并发请求

有的时候,我们可能需要同时发送两个请求,需要两个结果都返回了在进行数据处理

axios提供了一个all方法帮我们处理并发请求,使用方式和promiseall方法使用类似,出入数组

例如:

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(resultes => {
    console.log(resultes);

})

数据结果:

image
4.2 取出数组中的数据

通过示例,并发请求返回的结果是一个数组,数组中包裹不同请求的结果,

如果把数据从数组中取出,我们可能会有如下的方法

1.通过下标取值

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(resultes => {
    // 通过索引拿到不同的数据
    let resutl1 = resultes[0];
    let resutl2 = resultes[1];

    console.log(resutl1);
    console.log(resutl2);
})

2.或者使用解构取值

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(([resutl1,resutl2]) => {
    // 通过解构取数据

    console.log(resutl1);
    console.log(resutl2);
})

以上两种方法都可以取出数据

同样axios也提供了一个spread方法把数据从数组中取出

axios.all([
    axios.get("https://jsonplaceholder.typicode.com/posts"),
    axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(axios.spread((resutl1,resutl2) => {
    // 通过axios的spread方法取出数据

    console.log(resutl1);
    console.log(resutl2);
}))

4.3 axios.all 方法的问题

axiosall方法和promiseall方法都有一个致命的缺点,就是一点有一个请求出现错误,那么整个请求都会出现错误.

但是axiosall方法比promise的好处就是,正常来说服务器都是连接正常,如果没有请求到数据也会返回成功的请求

就算没有拿到数据,本地和服务器之间的连接也是成功的,只不过服务器返回的是其实数据获取错误的信息并不是数据

无论如何,在使用时,要注意.

5 axios 请求配置

下面这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 get 方法。

5.1 常用配置选项

{
   // `url` 是用于请求的服务器 URL
  url: '/user',

  // `method` 是创建请求时使用的方法
  method: 'get', // default

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: 'https://some-domain.com/api/',

  // `params` 是即将与请求一起发送的 URL 参数
  // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
  params: {
    ID: 12345
  },

  // `data` 是作为请求主体被发送的数据
  // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  // 在没有设置 `transformRequest` 时,必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属:FormData, File, Blob
  // - Node 专属: Stream
  data: {
    firstName: 'Fred'
  },

  // 'proxy' 定义代理服务器的主机名称和端口
  // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
  // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `transformRequest` 允许在向服务器发送前,修改请求数据
  // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
  // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
  transformRequest: [function (data, headers) {
    // 对 data 进行任意转换处理
    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理
    return data;
  }],

  // `headers` 是即将被发送的自定义请求头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
  // 如果请求话费了超过 `timeout` 的时间,请求将被中断
  timeout: 1000,

}   

5.2 常用配置示例
axios.all([
    axios({
        baseURL:"https://jsonplaceholder.typicode.com" ,
        url: "/posts",
    }),
    axios({
        baseURL:"https://jsonplaceholder.typicode.com" ,
        url:"/posts/1"
    })
]).then(axios.spread((resutl1,resutl2) => {
    // 通过axios的spread方法取出数据
    console.log(resutl1);
    console.log(resutl2);
}))

每次发送请求都可以配置当前发送的内容

5.3 全局配置

前面讲的配置都在在每次发送请求前进行的配置,如果每次发送都需要用到一些相同的配置,那么我们就可以将这些配置提取出来成为全局配置

5.3.1 全局配置的方法
// 全局配置基本路径
axios.defaults.baseURL = "https://jsonplaceholder.typicode.com"
// 全局配置请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

一但全局配置,那么每次发送请求都会使用全局的配置

5.3.2 使用全局配置修改上面的示例
// 全局配置基本路径
axios.defaults.baseURL="https://jsonplaceholder.typicode.com" 

// 发送的两次请求都会使用全局配置的路径
axios.all([
    axios({
        url: "/posts",
    }),
    axios({
        url:"/posts/1"
    })
]).then(axios.spread((resutl1,resutl2) => {
    // 通过axios的spread方法取出数据

    console.log(resutl1);
    console.log(resutl2);
}))

使用全局配置依然可以正常获取数据

6. axios 实例

6.1 为什么要创建axios实例

随着项目的复杂度的提升,需要的数据量就会越来越多,出于服务器性能的考虑, 可能会将数据部署在多台服务器上,

此时单单只配置一个全局baseURL以及没法满足我们的需求,

此时需要使用axios实例,分别配置对于不同服务器数据的请求

6.2 创建axios实例

axios提供了一个create方法创建实例

语法格式如下:

const instance = axios.create(config);
// config为当前实例的配置对象

6.3 axios 实例的示例

通过axios向不同的服务器获取数据

// axios实例一
// instance 向 jsonplaceholder 发送请求
const instance = axios.create({
    baseURL: "https://jsonplaceholder.typicode.com" 
})
instance({
    url:"/posts"
}).then(res => {
    console.log(res);
})

// axios 实例二
// instance2 向 github 发送请求
const instance2 = axios.create({
    baseURL: "https://api.github.com/users" 
})
instance2({
    url:"/mojombo"
}).then(res => {
    console.log(res);
})

7. axios 封装

7.1 为什么要对 axios 进行封装

axios封装原因说明

  1. 如果不分装axios,就在所有需要数据的组件中通过axios发送请求
  2. 如果未来需要更换请求的第三方库,就需更换所有导入axios库的组件,
  3. 如果axios请求出现问题,需要调整,就需要在所有使用了axios的组件中进行调整,不利于后期维护

因此我们需要对axios进行封装,

这样所有需要发送请求的组件都只要使用我们封装的模块就可以了,

如果后期需要调整就只需要修改我们封装的模块就可以了

7.2 封装axios 代码
import axios from 'axios';

export function request(config){
    const instance = axios.create({
        baseURL: "https://api.github.com/users"
    })

    return instance(config)
}

8. axios 全局拦截器

axios在每一个请求配置中都有一个配置项用于拦截请求或响应结果

这个拦截请求只能拦截当前配置的请求. 如果我们希望拦截所有的请求,就需要使用全局拦截器

全局拦截器是会拦截所有的请求或响应

拦截器:就是在请求或响应被 thencatch 处理前拦截它们。


// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

9. 配置的优先级

通过上面的学习,知道了axios的配置有以下这些

  1. 默认配置,自带的
  2. 全局配置:axios.defaults.baseURL=""
  3. 实例配置: axios.create({baseURL:""})
  4. 发送请求配置:axios({baseURL:""})

这些配置的优先级为

配置以一个优先顺序进行合并。这个顺序是:

  1. lib/defaults.js 找到的库的默认值,
  1. 然后是全局defaults配置
  1. 然后是实例的 defaults 属性,
  1. 最后是请求的 config 参数。
后者将优先于前者。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容