共计 10318 个字符,预计需要花费 26 分钟才能阅读完成。
1. 简介
Axios 是一个基于 promise 的网络请求库,作用于 node.js 和浏览器中。它提供了许多强大的特性,比如拦截器、请求和响应转换、取消请求等。
具有如下特性:
- 从浏览器发出 XMLHttpRequests
- 从 node.js 发出 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- JSON 数据的自动转换
- 自动将数据对象序列化为正文编码
multipart/form-data
x-www-form-urlencoded
- 客户端支持防范 XSRF
项目地址:https://github.com/axios/axios
2. 安装
可以使用 npm
安装。
npm install axios
或者使用 cdn
进行导入。
<script src="https://cdn.jsdelivr.net/npm/axios@1.6.7/dist/axios.min.js"></script>
3. 配置与基本使用
3.1 默认配置
以下内容为 axios 的可配置项,可以在发送请求时传递特殊
{
// url 是请求的服务器 URL
url: '/user',
// method 是请求使用的方法
method: 'get', // 默认值
//baseURL 会被添加到url 前面,除非url 是绝对地址。
baseURL: 'https://some-domain.com/api/',
// transformRequest 允许在发送到服务器之前修改请求数据
// 仅适用于请求方法为 'PUT', 'POST', 'PATCH' 和 'DELETE'
// 数组中的最后一个函数必须返回字符串或者 Buffer、ArrayBuffer、FormData 或 Stream 的实例
// 您可以修改 headers 对象
transformRequest: [function (data, headers) {
// 对数据进行任何想要的转换
return data;
}],
// transformResponse 允许在传递给 then/catch 前修改响应数据
transformResponse: [function (data) {
// 对数据进行任何想要的转换
return data;
}],
// headers 是要发送的自定义头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// params 是要随请求发送的 URL 参数
// 必须是普通对象或 URLSearchParams 对象
params: {
ID: 12345
},
// data 是要作为请求体发送的数据
// 仅适用于请求方法 'PUT', 'POST', 'DELETE' 和 'PATCH'
// 当没有设置transformRequest 时,必须是以下类型之一:
// - 字符串、普通对象、ArrayBuffer、ArrayBufferView、URLSearchParams
// - 仅浏览器:FormData、File、Blob
// - 仅 Node:Stream、Buffer、FormData(form-data package)
data: {
firstName: 'Fred'
},
// 发送数据到主体的语法替代方案
// 方法为 post
// 仅发送值,不发送键
data: 'Country=Brasil&City=Belo Horizonte',
//timeout 指定请求超时的毫秒数
// 如果请求超时时间超过timeout,请求将被中止
timeout: 1000, // 默认值为0(无超时)
//responseType 表示服务器将以何种类型响应
// 选项有:'arraybuffer'、'document'、'json'、'text'、'stream'
// 仅浏览器:'blob'
responseType: 'json', // 默认值
//cancelToken 指定可用于取消请求的取消令牌
// (有关详情,请参见下面的取消部分)
cancelToken: new CancelToken(function (cancel) {
}),
// ==========================
// 以下内容没那么常用
// ==========================
//paramsSerializer 是一个可选配置,允许您自定义序列化params。
paramsSerializer: {
// 自定义编码器函数,以迭代方式发送键值对。
encode?: (param: string): string => { /* 在此处执行自定义操作并返回转换后的字符串 */ },
// 用于整个参数的自定义序列化函数。允许用户模仿 1.x 之前的行为。
serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ),
// 格式化参数中的数组索引的配置。
indexes: false // 三个可用选项:(1) indexes: null(导致无括号),(2) (default) indexes: false(导致空括号),(3) indexes: true(导致带索引的括号)。
},
//withCredentials 表示是否应使用凭据进行跨站点访问控制请求
withCredentials: false, // 默认值
//adapter 允许自定义处理请求,从而简化测试。
// 返回一个 Promise 并提供有效的响应(参见 lib/adapters/README.md)。
adapter: function (config) {
/* ... */
},
//auth 表示应该使用 HTTP 基本身份验证,并提供凭据。
// 这将设置一个Authorization 头,覆盖任何现有的
// 使用headers 设置的Authorization 自定义头
// 请注意,只有 HTTP 基本身份验证可以通过此参数配置。
// 对于 Bearer 令牌等,请改用Authorization 自定义头。
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
//responseEncoding 表示用于解码响应的编码(仅 Node.js)
// 注意:对于 'stream' 或客户端请求的responseType,将被忽略
// 选项有:'ascii'、'ASCII'、'ansi'、'ANSI'、'binary'、'BINARY'、'base64'、'BASE64'、'base64url'、
// 'BASE64URL'、'hex'、'HEX'、'latin1'、'LATIN1'、'ucs-2'、'UCS-2'、'ucs2'、'UCS2'、'utf-8'、'UTF-8'、
// 'utf8'、'UTF8'、'utf16le'、'UTF16LE'
responseEncoding: 'utf8', // 默认值
//xsrfCookieName 是用作 xsrf 令牌值的 cookie 的名称
xsrfCookieName: 'XSRF-TOKEN', // 默认值
//xsrfHeaderName 是携带 xsrf 令牌值的 HTTP 头的名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值
//undefined(默认)- 仅为同源请求设置 XSRF 头
withXSRFToken: boolean | undefined | ((config: InternalAxiosRequestConfig) => boolean | undefined),
//onUploadProgress 允许处理上传的进度事件
// 浏览器和 Node.js
onUploadProgress: function ({loaded, total, progress, bytes, estimated, rate, upload = true}) {
// 对 Axios 进度事件进行任何操作
},
//onDownloadProgress 允许处理下载的进度事件
// 浏览器和 Node.js
onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) {
// 对 Axios 进度事件进行任何操作
},
//maxContentLength 定义在 Node.js 中允许的 HTTP 响应内容的最大大小(以字节为单位)
maxContentLength: 2000,
//maxBodyLength(仅限 Node 选项)定义允许的 HTTP 请求内容的最大大小(以字节为单位)
maxBodyLength: 2000,
//validateStatus 定义是否应解析或拒绝给定的 HTTP 响应状态码的承诺。
// 如果validateStatus 返回true(或设置为null 或undefined),则承诺将被解析;否则,承诺将被拒绝。
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认值
},
//maxRedirects 定义在 Node.js 中要遵循的最大重定向次数。
// 如果设置为 0,则不会遵循重定向。
maxRedirects: 21, // 默认值
//beforeRedirect 定义在重定向之前将调用的函数。
// 使用此功能可以在重定向时调整请求选项,
// 检查最新的响应头,
// 或通过抛出错误来取消请求
// 如果maxRedirects 设置为 0,则不使用beforeRedirect。
beforeRedirect: (options, { headers }) => {
if (options.hostname === "example.com") {
options.auth = "user:password";
}
},
//socketPath 定义要在 Node.js 中使用的 UNIX Socket。
// 例如 '/var/run/docker.sock' 以将请求发送到 Docker 守护进程。
// 只能指定socketPath 或proxy 其中之一。
// 如果两者都指定,则使用socketPath。
socketPath: null, // 默认值
//transport 确定要使用的传输方法来进行请求。如果定义了,将使用它。否则,如果maxRedirects 为 0,则使用默认的http 或https 库,具体取决于protocol 中指定的协议。否则,将使用httpFollow 或httpsFollow 库,再次取决于协议,它可以处理重定向。
transport: undefined, // 默认值
//httpAgent 和httpsAgent 定义在 Node.js 中执行 http 和 https 请求时要使用的自定义代理。这允许添加选项,如keepAlive,这些选项默认情况下未启用。
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
//proxy 定义代理服务器的主机名、端口和协议。
// 您还可以使用常规的http_proxy 和https_proxy 环境变量来定义您的代理。
// 如果您使用环境变量进行代理配置,您还可以定义一个no_proxy 环境变量,作为不应代理的域名的逗号分隔列表。
// 使用false 禁用代理,忽略环境变量。
//auth 表示应该使用 HTTP 基本身份验证来连接代理,并提供凭据。
// 这将设置一个Proxy-Authorization 头,覆盖任何现有的
// 使用headers 设置的Proxy-Authorization 自定义头
// 如果代理服务器使用 HTTPS,则必须将协议设置为https。
proxy: {
protocol: 'https',
host: '127.0.0.1',
// 如果定义了两者,则 'host' 优先于 'hostname'
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// 使用 AbortController 取消 Axios 请求的另一种方法
signal: new AbortController().signal,
//decompress 表示是否应自动解压响应体
// 如果设置为true,还会从所有解压的响应对象的 'content-encoding' 头中移除
// - 仅 Node(XHR 无法关闭解压缩)
decompress: true, // 默认值
//insecureHTTPParser 布尔值。
// 指示是否使用不安全的 HTTP 解析器接受无效的 HTTP 标头。
// 这可能允许与不符合规范的 HTTP 实现进行交互。
// 应避免使用不安全的解析器。
// 有关选项,请参见 https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback
// 也请参见 https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none
insecureHTTPParser: undefined, // 默认值
// 用于向后兼容的过渡选项,可能会在较新版本中删除
transitional: {
// 静默 JSON 解析模式
//true - 忽略 JSON 解析错误并将 response.data 设置为 null(旧行为)
//false - 如果 JSON 解析失败则抛出 SyntaxError(注意:responseType 必须设置为 'json')
silentJSONParsing: true, // 当前 Axios 版本的默认值
// 即使responseType 不是 'json',也尝试解析响应字符串为 JSON
forcedJSONParsing: true,
// 在请求超时时抛出 ETIMEDOUT 错误,而不是通用的 ECONNABORTED
clarifyTimeoutError: false,
},
env: {
// 用于自动将 payload 序列化为 FormData 对象的 FormData 类
FormData: window?.FormData || global?.FormData
},
formSerializer: {
visitor: (value, key, path, helpers) => {}; // 自定义访问器函数以序列化表单值
dots: boolean; // 使用点代替括号格式
metaTokens: boolean; // 保留特殊结尾,如 {} 在参数键中
indexes: boolean; // 数组索引格式 null - 无括号,false - 空括号,true - 带索引的括号
},
// 仅限 http 适配器(Node.js)
maxRate: [
100 * 1024, // 100KB/s 的上传限制
100 * 1024 // 100KB/s 的下载限制
]
}
3.2 基本使用
直接使用 Axios 函数可以通过简单的静态方法发送 HTTP 请求,而无需创建 Axios 实例。另外,axios 发送的请求都是返回一个 Promise 对象。
-
axios.request(config): 发送自定义配置的 HTTP 请求。
-
axios.get(url[, config]): 发送 GET 请求。
-
axios.post(url[, data[, config]]): 发送 POST 请求。
-
axios.patch(url[, data[, config]]): 发送 PATCH 请求。
-
axios.put(url[, data[, config]])**: 发送 PUT 请求。
-
axios.delete(url[, config]): 发送 DELETE 请求。
-
axios.head(url[, config]): 发送 HEAD 请求。
-
axios.options(url[, config]): 发送 OPTIONS 请求。
- axios.request
这里直接传递一个 config
对象。
axios.request({
url: "http://localhost:3000/posts",
method: "get"
})
.then((response) => {
console.log(response);
})
.catch(error => {
console.error(error);
});
- axios.get
axios.get('http://localhost:3000/posts')
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
如果定义 baseUrl
会让请求看起来更加简洁。
axios.defaults.baseURL = 'http://localhost:3000';
axios.get('/posts')
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
- axios.post
axios.defaults.baseURL = 'http://localhost:3000';
axios.post("/posts", {
title: "test",
views: 1000
})
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
或者将 data 定义在外面。
axios.defaults.baseURL = 'http://localhost:3000';
const data = {
title: "test",
views: 1000
}
axios.post("/posts", postData)
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
- axios.put
在 restful 风格 api 中,put 用于更新资源,并且是完全替换。
axios.defaults.baseURL = 'http://localhost:3000';
const data = {
id: 1,
title: "test",
views: 1000
};
axios.put("/posts/1", data)
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
- axios.patch
在 restful 风格 api 中,patch 同样用于更新资源,并且是部分替换。
axios.defaults.baseURL = 'http://localhost:3000';
// 此时不会替换 views
const data = {
id: 1,
title: "test2222222"
};
axios.patch("/posts/1", data)
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
- axios.delete
axios.defaults.baseURL = 'http://localhost:3000';
axios.delete("/posts/1")
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
4. axios
axios 可以使用自定义配置创建实例,例如指定不同的 baseurl
或不同的超时事件 timeout
。
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000
});
// 该接口比较特殊,需要设置较长的超时事件
const instance2 = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 30000
});
创建好以后和 axios 使用的方式是一样的。
5. 拦截器
axios 拦截器允许在请求或响应被 then 或 catch 处理之前拦截它们。这提供了一种在请求或响应被处理前,对它们进行全局的、统一的处理的方式。
5.1 请求拦截器
请求拦截器允许你在请求被发送之前进行一些操作,比如修改请求头部信息或添加额外的数据。例如,最常见的是在请求头添加 token:
axios.interceptors.request.use(
function(config) {
// 设置 token
const token = 'xxx';
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
function(error) {
return Promise.reject(error);
}
);
axios.interceptors.request.use
函数接收两个参数:一个成功的回调函数和一个失败的回调函数。成功的回调函数接收一个 config
对象作为参数,可以在这个函数中修改 config
对象的属性。失败的回调函数则接收一个错误对象作为参数,并且可以在这个函数中处理请求发送失败的情况。
5.2 响应拦截器
响应拦截器允许在响应被处理之前进行一些操作,比如对返回的数据进行处理或者统一处理错误信息。例如,最常见的是对没有正常返回的数据弹窗提示:
axios.interceptors.response.use(
function(config) {
const res = response.data
// 对非正常请求做处理
if (res.code !== 20000) {
// 做一些处理,例如弹出错误提示等
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
function(error) {
return Promise.reject(error);
}
)
同样,axios.interceptors.response.use
函数也接收两个参数:一个成功的回调函数和一个失败的回调函数。成功的回调函数接收一个 response
对象作为参数,可以在这个函数中处理返回的数据。失败的回调函数则接收一个错误对象作为参数,并且可以在这个函数中处理请求发送失败的情况。
5.3 执行顺序
请求拦截:axios 请求拦截会先执行最后指定的回调函数,依次向前面执行,先进后出
响应拦截:axios 响应拦截会先执行最先指定的回调函数,依次向后面执行,先进先出
import axios from 'axios';
// 添加第一个请求拦截器
axios.interceptors.request.use(config => {
console.log('请求拦截器 1:添加 auth token');
config.headers['Authorization'] = 'Bearer yourAuthToken';
return config;
}, error => {
return Promise.reject(error);
});
// 添加第二个请求拦截器
axios.interceptors.request.use(config => {
console.log('请求拦截器 2:添加额外的请求头');
config.headers['X-Extra-Header'] = 'extraValue';
return config;
}, error => {
return Promise.reject(error);
});
// 添加第一个响应拦截器
axios.interceptors.response.use(response => {
console.log('响应拦截器 1:检查响应状态码');
if (response.status === 200) {
console.log('响应状态 OK');
}
return response;
}, error => {
return Promise.reject(error);
});
// 添加第二个响应拦截器
axios.interceptors.response.use(response => {
console.log('响应拦截器 2:转换响应数据');
// 假设我们要转换响应数据的格式
response.data = { transformed: true, originalData: response.data };
return response;
}, error => {
return Promise.reject(error);
});
// 发起一个请求
axios.get('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
console.log('转换后的响应数据:', response.data);
})
.catch(error => {
console.error('请求失败:', error);
});
执行结果。
请求拦截器 2:添加额外的请求头
请求拦截器 1:添加 auth token
响应拦截器 1:检查响应状态码
响应状态 OK
响应拦截器 2:转换响应数据
转换后的响应数据: { transformed: true, originalData: ... }
提醒:本文发布于229天前,文中所关联的信息可能已发生改变,请知悉!