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 请求的特点
- 支持node端和浏览器端: 同样的API,node和浏览器全支持,平台切换无压力
- 支持 Promise: 使用Promise管理异步,告别传统callback方式
- 丰富的配置项: 支持请求和响应的拦截, 提前处理请求和响应数据
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 请求方式
- axios(config)
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.options(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]]
上面基本的示例中,我们是在axios()
请求的配置对象中配置请求方式,axios
也提供了通过不同的方式发送请求
指定了请求方式发送请求说明
-
第一个参数将是发送的
url
, -
第二个参数是请求的配置对象,可以省略,使用默认配置
示例:
不是用配置对象
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
方法帮我们处理并发请求,使用方式和promise
的all
方法使用类似,出入数组
例如:
axios.all([
axios.get("https://jsonplaceholder.typicode.com/posts"),
axios.post("https://jsonplaceholder.typicode.com/posts")
]).then(resultes => {
console.log(resultes);
})
数据结果:
image4.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 方法的问题
axios
的all
方法和promise
的all
方法都有一个致命的缺点,就是一点有一个请求出现错误,那么整个请求都会出现错误.
但是axios
的all
方法比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
封装原因说明
- 如果不分装
axios
,就在所有需要数据的组件中通过axios
发送请求 - 如果未来需要更换请求的第三方库,就需更换所有导入
axios
库的组件, - 如果
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
在每一个请求配置中都有一个配置项用于拦截请求或响应结果
这个拦截请求只能拦截当前配置的请求. 如果我们希望拦截所有的请求,就需要使用全局拦截器
全局拦截器是会拦截所有的请求或响应
拦截器:就是在请求或响应被 then
或 catch
处理前拦截它们。
// 添加请求拦截器
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
的配置有以下这些
- 默认配置,自带的
- 全局配置:
axios.defaults.baseURL=""
- 实例配置:
axios.create({baseURL:""})
- 发送请求配置:
axios({baseURL:""})
这些配置的优先级为
配置以一个优先顺序进行合并。这个顺序是:
- 在
lib/defaults.js
找到的库的默认值,
- 然后是全局
defaults
配置
- 然后是实例的
defaults
属性,
- 最后是请求的
config
参数。后者将优先于前者。
网友评论