Skip to content
从创建实例开始:axios.create 与默认配置
Axios 的全局对象 axios 本身就可以发送请求。不过全局对象只有一份默认配置,项目里同时对接多个后端服务,或者需要按模块区分超时时间时,直接在 axios.defaults 上修改会互相干扰。
axios.create(config) 用于创建独立的请求实例。它返回一个拥有独立默认配置的实例,与其他实例以及全局 axios 互不影响。
js
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000
});
instance.get('/users');
// 实际请求:GET https://api.example.com/usersaxios.create() 本身不会发送请求。它只负责创建实例并初始化默认配置。返回的实例拥有 request、get、post、put、patch、delete 等方法。
js
const instance = axios.create();
instance.request({
method: 'get',
url: '/users'
});
// 等价于 instance.get('/users')请求配置全解析:AxiosRequestConfig
Axios 的每个请求方法都接受一个配置对象。在官方文档中,这个对象被称为 AxiosRequestConfig。它决定请求发往哪里、使用什么方法、携带哪些参数,以及如何处理响应。
url、method、baseURL
url 是请求路径,可以写相对路径,也可以写绝对 URL。
method 是 HTTP 请求方法,默认值是 'get'。使用 request() 时必须显式传入 method;使用 get()、post() 等别名方法时,method 已经预设好了。
baseURL 会自动拼在 url 前面。如果 url 是绝对 URL,baseURL 不生效。
js
const instance = axios.create({
baseURL: 'https://api.example.com/v1'
});
instance.get('/users');
// 请求 URL:https://api.example.com/v1/users
instance.get('https://cdn.example.com/app.js');
// 请求 URL:https://cdn.example.com/app.jsparams 与 data
params 在发送前序列化为 URL 查询字符串,data 作为请求体发送。
js
instance.request({
method: 'post',
url: '/users',
params: { source: 'admin' },
data: { name: '张三' }
});
// 实际请求:POST /users?source=admin
// 请求体:{"name":"张三"}从配置字段的角度看,两者的区别在于序列化位置:params 进入 query,data 进入 body。paramsSerializer 配置项可以自定义查询字符串的序列化方式,例如处理数组或嵌套对象时的格式。
headers
headers 配置自定义请求头。单次请求中的 headers 会与实例默认的 headers 合并,并且只对当前请求生效。
js
instance.get('/users', {
headers: {
Authorization: 'Bearer token'
}
});
// 本次请求携带 Authorization 请求头,实例 defaults 不受影响timeout
timeout 指定请求超时时间,单位是毫秒。0 表示没有超时限制。不设置时,Axios 默认不限制超时时间。
js
const instance = axios.create({ timeout: 5000 });
instance.get('/slow-api').catch(error => {
console.log(error.code); // ECONNABORTED
});请求超过 5000 毫秒没有完成时,Promise 进入 rejected 状态,错误对象的 code 通常为 'ECONNABORTED'。
responseType
responseType 决定服务端响应数据以什么形式存入 response.data。默认值是 'json'。
| responseType | response.data 的形态 | 可用环境 |
|---|---|---|
json | 解析后的对象或数组 | 浏览器、Node.js |
text | 字符串 | 浏览器、Node.js |
arraybuffer | ArrayBuffer | 浏览器、Node.js |
blob | Blob | 浏览器 |
document | HTMLDocument | 浏览器 |
stream | 流对象 | Node.js |
js
async function fetchText() {
const response = await instance.get('/api/file', {
responseType: 'text'
});
console.log(typeof response.data); // string
}validateStatus
validateStatus 接收 HTTP 状态码,返回布尔值。返回 true 时 Promise 进入 fulfilled 状态,返回 false 时进入 rejected 状态。默认规则是 status >= 200 && status < 300。
js
instance.get('/legacy-api', {
validateStatus: status => status === 200 || status === 404
}).then(response => {
// 404 也会进入这里
console.log(response.status);
});validateStatus 只改变 Promise 的状态,不会改变 response 对象的结构。
其他配置字段
AxiosRequestConfig 中还有一些字段,在需要时才会用到:
| 字段 | 作用 |
|---|---|
auth | HTTP Basic 认证,自动生成 Authorization 头 |
withCredentials | 跨域请求是否携带 Cookie |
paramsSerializer | 自定义 params 的序列化函数 |
transformRequest | 请求发送前对 data 做转换 |
transformResponse | 响应返回后对 data 做转换 |
signal | 与 AbortController 配合取消请求 |
cancelToken | 旧的请求取消方式 |
proxy | Node.js 环境下配置代理 |
adapter | 自定义请求适配函数 |
transformRequest、adapter 等字段属于 Axios 内部机制的一部分,日常使用中很少需要直接修改。
默认配置:defaults 与合并规则
每个 Axios 实例都有一个 defaults 对象,保存该实例的默认配置。axios.create(config) 会把全局 axios.defaults 合并到实例的 defaults 中,再把 config 传入的字段合并进去。因此实例的 defaults 已经包含了创建时的全局默认值。
请求发出时,实际生效的配置由实例的 defaults 与单次请求配置合并而成。讨论优先级时,可以按来源从低到高分为三层:
- 全局默认配置(
axios.defaults) - 实例默认配置(
axios.create(config)设置,或之后通过instance.defaults修改) - 单次请求传入的配置
同名字段,优先级高的覆盖优先级低的。headers 字段比较特殊,会被递归合并,也就是子级键值会逐项合并而不是整体覆盖。
js
axios.defaults.timeout = 8000;
axios.defaults.headers.common['X-Global'] = 'global';
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000
});
console.log(instance.defaults.timeout);
// 5000,实例配置覆盖了全局配置
console.log(instance.defaults.headers.common['X-Global']);
// 'global',全局 header 在 create 时被继承实例创建之后再修改全局 axios.defaults,不会影响已经创建的实例。
js
axios.defaults.timeout = 12000;
console.log(instance.defaults.timeout);
// 仍然是 5000实例自身的默认配置可以通过 instance.defaults 修改。
js
instance.defaults.timeout = 10000;
instance.defaults.headers.common['X-App-Version'] = '1.0';
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';响应结构:AxiosResponse
请求成功时,Axios 会把 HTTP 响应包装成一个结构统一的对象。这个对象在官方文档中称为 AxiosResponse,包含 data、status、statusText、headers、config、request 六个字段。
js
async function fetchUser() {
const response = await instance.get('/users/1');
const { data, status } = response;
console.log(status, data);
}data
response.data 是响应体。默认情况下,Axios 会尝试把 JSON 字符串解析成 JavaScript 对象。
js
console.log(response.data.name);status
response.status 是 HTTP 状态码,数字类型。
js
console.log(response.status); // 200statusText
response.statusText 是 HTTP 状态文本。HTTP/2 协议中没有状态文本这个概念,所以使用 HTTP/2 时该字段可能为空字符串。
js
console.log(response.statusText); // 'OK'headers
response.headers 是响应头对象。键名通常被归一化为小写。
js
console.log(response.headers['content-type']);config
response.config 是本次请求实际使用的配置对象。它包含合并后的完整请求配置,传入的 url、method、params、headers、timeout、validateStatus 等字段都可以在这里回溯。
js
async function fetchUsers() {
const response = await instance.get('/users', {
params: { page: 1 }
});
console.log(response.config.url); // '/users'
console.log(response.config.method); // 'get'
console.log(response.config.params); // { page: 1 }
console.log(response.config.timeout); // 5000
}request
response.request 是底层请求对象。浏览器中通常是 XMLHttpRequest 实例,Node.js 中通常是 ClientRequest 实例。常规业务代码中很少直接使用。
HTTP 错误时的 response
当 HTTP 状态码不在成功范围内时,Promise 不会 resolve,而是 reject 一个 AxiosError。此时可以通过 error.response 拿到一个结构与 AxiosResponse 相同的对象。
js
async function fetchMissing() {
try {
await instance.get('/not-found');
} catch (error) {
console.log(error.response.status); // 404
console.log(error.response.data); // 服务端返回的响应体
}
}配置与响应:一次完整请求的字段对照
下面用一个完整示例展示请求配置、实际发送行为与响应字段的对应关系。
js
async function fetchUsers() {
try {
const response = await instance.get('/users', {
params: { page: 1, size: 20 },
headers: {
Authorization: 'Bearer abc123'
}
});
console.log(response.status, response.statusText);
console.log(response.data);
// response.config 保存合并后的完整请求配置
console.log(response.config.baseURL);
// 'https://api.example.com'
console.log(response.config.url);
// '/users'
console.log(response.config.method);
// 'get'
console.log(response.config.params);
// { page: 1, size: 20 }
console.log(response.config.timeout);
// 5000
} catch (error) {
if (error.response) {
console.log(error.response.status);
console.log(error.response.data);
} else {
console.log(error.code);
}
}
}配置字段与响应字段的对应关系可以整理成下面的表。
| 配置字段 | 请求阶段行为 | 响应中的对应物 |
|---|---|---|
baseURL + url | 拼出完整请求 URL | response.config.baseURL、response.config.url |
method | 设置 HTTP 方法 | response.config.method |
params | 序列化为 URL 查询字符串 | response.config.params |
headers | 组成请求头 | response.config.headers;响应头见 response.headers |
data | 写入请求体 | 服务端处理后的结果在 response.data |
timeout | 控制请求超时 | 超时进入 error,没有 response |
responseType | 决定响应数据的解析方式 | response.data 的形态 |
validateStatus | 决定 HTTP 状态码是否算成功 | 返回 false 时进入 error.response |
注意点:timeout 与 responseType
timeout 的实际表现
timeout: 0 表示没有超时限制,不是“立即超时”。超时后 Promise 进入 rejected 状态,错误对象中通常包含 code: 'ECONNABORTED',message 类似 timeout of 5000ms exceeded。
js
const instance = axios.create({ timeout: 2000 });
instance.get('/slow-api')
.then(response => {
console.log('成功', response.data);
})
.catch(error => {
console.log(error.code); // ECONNABORTED
console.log(error.message); // timeout of 2000ms exceeded
});请求超时和请求取消是两种不同的错误。取消请求时,错误码通常是 ERR_CANCELED(不同 Axios 版本中具体错误码可能有差异),与 ECONNABORTED 不同。
responseType 对 data 的影响
responseType 直接影响 response.data 的类型。
js
async function fetchData() {
const textRes = await instance.get('/api/version', {
responseType: 'text'
});
console.log(typeof textRes.data); // string
const bufferRes = await instance.get('/api/export', {
responseType: 'arraybuffer'
});
console.log(bufferRes.data instanceof ArrayBuffer); // true
}在浏览器中,blob 和 document 类型分别返回 Blob 和 HTMLDocument。在 Node.js 中,stream 类型返回一个流对象,流只能被读取一次,读取后不能再次消费。
GET 的 data 与 POST 的 params
配置对象并不限制 params 和 data 的组合方式。GET 请求可以配置 data,POST 请求也可以配置 params。Axios 不会阻止这种写法。但 HTTP 语义上,GET 的请求体通常不会被服务端解析,实际请求中应避免依赖这种用法。
本章小结
axios.create(config)创建独立实例,实例拥有自己的defaults默认配置。- AxiosRequestConfig 通过
url、method、baseURL、params、data、headers、timeout、responseType、validateStatus等字段控制请求行为。 - 配置合并优先级从低到高是:全局
axios.defaults、实例defaults、单次请求配置。headers会递归合并。 - 成功响应被包装为 AxiosResponse 对象,核心字段是
data、status、statusText、headers、config、request。 response.config保存本次请求的完整配置,可以用来反向查看请求参数。timeout超时后错误码通常为ECONNABORTED,responseType决定response.data的形态。
参考链接
- Axios 官方文档:Request Config(请求配置) https://axios-http.com/docs/req_config
- Axios 官方文档:Response Schema(响应结构) https://axios-http.com/docs/res_schema
- Axios 官方文档:Axios Instance(实例) https://axios-http.com/docs/instance
