Axios 笔记
约 4624 字大约 15 分钟
2025-12-14
Axios 是一个基于 promise 网络请求库,作用于 node.js 和浏览器中。 一套代码可以运行在浏览器和 node.js 中,在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequest。
用例
pnpm add axiosimport axios from 'axios'
axios.get('/user?id=admin')
.then(function (response) {
// 处理成功情况
console.log(response);
})
.catch(function (error) {
// 处理错误情况
console.log(error);
})
.finally(function () {
// 总是会执行
});也可以这样写
axios.get('/user', {
params: {
id: admin
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
// 总是会执行
});支持 async/await 用法
async function getUser() {
try {
const response = await axios.get('/user?id=admin');
console.log(response);
} catch (error) {
console.error(error);
}
}发起一个 POST 请求
axios.post('/user', {
firstName: 'firstName',
lastName: 'lastName'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});发起多个并发请求
function getUserAccount() {
return axios.get('/user/admin');
}
function getUserPermissions() {
return axios.get('/user/admin/permissions');
}
const [acct, perm] = await Promise.all([getUserAccount(), getUserPermissions()]);
// OR
Promise.all([getUserAccount(), getUserPermissions()])
.then(function ([acct, perm]) {
// ...
});将 HTML Form 转换成 JSON 进行请求
const {data} = await axios.post('/user', document.querySelector('#my-form'), {
headers: {
'Content-Type': 'application/json'
}
})multipart/form-data
const {data} = await axios.post('https://httpbin.org/post', {
firstName: 'Fred',
lastName: 'Flintstone',
orders: [1, 2, 3],
photo: document.querySelector('#fileInput').files
}, {
headers: {
'Content-Type': 'multipart/form-data'
}
}
)application/x-www-form-urlencoded
const {data} = await axios.post('https://httpbin.org/post', {
firstName: 'Fred',
lastName: 'Flintstone',
orders: [1, 2, 3]
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})API
可以向 axios 传递相关配置来创建请求
axios(config)
配置详细
export interface AxiosRequestConfig<D = any> {
// 请求的 URL,可以是相对路径或绝对路径
url?: string;
// HTTP 请求方法,如 get / post / put / delete
method?: Method | string;
// 基础 URL,会自动与 url 拼接
baseURL?: string;
// 是否允许使用绝对 URL(不与 baseURL 拼接)
allowAbsoluteUrls?: boolean;
// 请求发送前,对请求数据进行转换(如 JSON.stringify)
transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
// 响应数据返回给 then/catch 前的转换处理
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
// 请求头配置(支持通用头 + 方法专用头)
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
// URL 查询参数(?a = 1&b = 2)
params?: any;
// params 的序列化方式(如 qs、自定义格式)
paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer;
// 请求体数据(POST / PUT / PATCH)
data?: D;
// 请求超时时间(毫秒)
timeout?: Milliseconds;
// 超时后抛出的错误信息
timeoutErrorMessage?: string;
// 是否携带 cookie(跨域时常用)
withCredentials?: boolean;
// 自定义请求适配器(xhr / http / fetch)
adapter?: AxiosAdapterConfig | AxiosAdapterConfig[];
// HTTP 基础认证(Authorization: Basic)
auth?: AxiosBasicCredentials;
// 响应数据类型(json / blob / arraybuffer 等)
responseType?: ResponseType;
// 响应编码(Node.js 环境)
responseEncoding?: responseEncoding | string;
// XSRF 防护:cookie 名称
xsrfCookieName?: string;
// XSRF 防护:header 名称
xsrfHeaderName?: string;
// 上传进度回调(仅浏览器)
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
// 下载进度回调(浏览器 / Node)
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void;
// 响应内容最大长度(Node.js)
maxContentLength?: number;
// 自定义 HTTP 状态码校验规则
validateStatus?: ((status: number) => boolean) | null;
// 请求体最大大小(Node.js)
maxBodyLength?: number;
// 最大重定向次数(Node.js)
maxRedirects?: number;
// 请求限速(上传 / 下载)
maxRate?: number | [MaxUploadRate, MaxDownloadRate];
// 重定向前的回调(Node.js)
beforeRedirect?: (
options: Record<string, any>,
responseDetails: {
headers: Record<string, string>,
statusCode: HttpStatusCode
}
) => void;
// Unix Socket 路径(Node.js)
socketPath?: string | null;
// 自定义底层传输实现
transport?: any;
// 自定义 HTTP Agent(Node.js)
httpAgent?: any;
// 自定义 HTTPS Agent(Node.js)
httpsAgent?: any;
// 代理配置,false 表示禁用代理
proxy?: AxiosProxyConfig | false;
// 取消请求的 token(旧方案)
cancelToken?: CancelToken;
// 是否自动解压响应数据(Node.js)
decompress?: boolean;
// Axios 过渡期配置(兼容旧行为)
transitional?: TransitionalOptions;
// AbortController 信号(推荐的取消请求方式)
signal?: GenericAbortSignal;
// 是否启用不安全的 HTTP 解析器(Node.js)
insecureHTTPParser?: boolean;
// 运行环境相关配置(fetch / Request / Response)
env?: {
FormData?: new (...args: any[]) => object;
fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
Request?: new (input: URL | Request | string, init?: RequestInit) => Request;
Response?: new (
body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null,
init?: ResponseInit
) => Response;
};
// 表单数据序列化配置
formSerializer?: FormSerializerOptions;
// IP 地址族(IPv4 / IPv6)
family?: AddressFamily;
// 自定义 DNS lookup 方法(Node.js)
lookup?: (
(hostname: string, options: object, cb: (
err: Error | null,
address: LookupAddress | LookupAddress[],
family?: AddressFamily
) => void)
|
((hostname: string, options: object) => Promise<
[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily]
| LookupAddress
>)
);
// 是否自动携带 XSRF token(或动态判断)
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
// JSON.parse 时的 reviver 函数
parseReviver?: (this: any, key: string, value: any) => any;
// fetch API 的额外配置(不含 body / headers / method / signal)
fetchOptions?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'> | Record<string, any>;
// HTTP 协议版本(1 或 2)
httpVersion?: 1 | 2;
// HTTP/2 专用配置
http2Options?: Record<string, any> & {
sessionTimeout?: number;
};
}发起一个 post 请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});在 node.js 用 GET 请求获取远程图片
axios({
method: 'get',
url: 'http://bit.ly/2mTM3nY',
responseType: 'stream'
})
.then(function (response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});axios(url [, config])
发起一个 GET 请求 (默认请求方式)
axios('/user/12345');请求方式别名
为了方便起见,已经为所有支持的请求方法提供了别名。
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.postForm(url [, data[, config]])axios.putForm(url [, data[, config]])axios.patchForm(url [, data[, config]])
注意:在使用别名方法时, url、method、data 这些属性都不必在配置中指定。
实例
使用自定义配置新建一个实例
axios.create([config])
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});以下是可用的实例方法。指定的配置将与实例的配置合并。
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#getUri([config])
除了像 instance.get() 或 instance.post() 这样的便捷方法外,您还可以直接用配置对象调用 Axios 实例。这与 axios(config) 的用法相同,适用于需要基于原始配置重新发送请求的场景。
const instance = axios.create({ baseURL: '/api' });
// 类似于 axios(config)
instance({
url: '/users',
method: 'get'
});这种方式便于实现重试逻辑,例如处理认证失败时:
instance.interceptors.response.use(undefined, async (error) => {
if (error.response?.status === 401) {
await refreshToken();
return instance(error.config); // 重新发送原始请求
}
throw error;
});企业级 Axios 封装
有两种意义上的“全局”
真·全局(axios 默认实例)
axios.interceptors.request.use(...)
axios.interceptors.response.use(...)不推荐,原因:
- 污染所有 axios 使用场景
- 第三方库用 axios 也会被你拦截
推荐全局使用统一的 axios 实例 + 统一拦截策略
// 所有请求都用这个 instance
export default instance;request.ts
// src/api/request.ts
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse
} from 'axios';
/* ==== ==== ==== ==== ==== Token 工具(示例) ==== ==== ==== ==== ==== */
function getToken() {
return localStorage.getItem('access_token');
}
function setToken(token: string) {
localStorage.setItem('access_token', token);
}
// 模拟刷新 token
async function refreshToken(): Promise<string> {
const res = await axios.post('/refresh-token');
const newToken = res.data.token;
setToken(newToken);
return newToken;
}
/* ==== ==== ==== ==== ==== 创建实例 ==== ==== ==== ==== ==== */
const instance: AxiosInstance = axios.create({
baseURL: 'http://localhost:3000',
timeout: 5000,
withCredentials: true // 是否携带 cookie(按需)
});
/* ==== ==== ==== ==== ==== 请求拦截器 ==== ==== ==== ==== ==== */
instance.interceptors.request.use(
(config: AxiosRequestConfig) => {
const token = getToken();
// 自动注入 token
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
// 这里可以:
// - 打 loading
// - 统一加语言、租户 ID
// - 参数签名
return config;
},
(error) => {
// 请求还没发出去就失败
return Promise.reject(error);
}
);
/* ==== ==== ==== ==== ==== 响应拦截器(核心) ==== ==== ==== ==== ==== */
// 是否正在刷新 token
let isRefreshing = false;
// 刷新期间的请求队列
let requestQueue: Array<(token: string) => void> = [];
instance.interceptors.response.use(
(response: AxiosResponse) => {
// 👉 统一返回 data,业务层更干净
return response.data;
},
async (error) => {
const { response, config } = error;
// 没有 response,一般是网络错误 / 超时
if (!response) {
console.error('网络异常');
return Promise.reject(error);
}
/* ==== ==== == 401:token 失效处理 == ==== ==== */
if (response.status === 401 && !config._retry) {
config._retry = true;
// 已经在刷新 token,把请求放进队列
if (isRefreshing) {
return new Promise(resolve => {
requestQueue.push((token: string) => {
config.headers.Authorization = `Bearer ${token}`;
resolve(instance(config));
});
});
}
isRefreshing = true;
try {
const newToken = await refreshToken();
isRefreshing = false;
// 执行队列中的请求
requestQueue.forEach(cb => cb(newToken));
requestQueue = [];
// 重试当前请求
config.headers.Authorization = `Bearer ${newToken}`;
return instance(config);
} catch (e) {
isRefreshing = false;
requestQueue = [];
// 👉 刷新失败:通常需要登出
console.error('登录已过期');
// redirectToLogin();
return Promise.reject(e);
}
}
/* ==== ==== == 其他全局错误处理 == ==== ==== */
switch (response.status) {
case 403:
console.error('没有权限');
break;
case 500:
console.error('服务器错误');
break;
default:
console.error('请求错误', response.status);
}
return Promise.reject(error);
}
);
export default instance;请求配置
这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 GET 方法。
{
// `url` 是用于请求的服务器 URL
url: '/user',
// `method` 是创建请求时使用的方法
method: 'get', // 默认值
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 数组中最后一个函数必须返回一个字符串, 一个 Buffer 实例,ArrayBuffer,FormData,或 Stream
// 你可以修改请求头。
transformRequest: [function (data, headers) {
// 对发送的 data 进行任意转换处理
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对接收的 data 进行任意转换处理
return data;
}],
// 自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// `params` 是与请求一起发送的 URL 参数
// 必须是一个简单对象或 URLSearchParams 对象
params: {
ID: 12345
},
// `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 (引导空字符串).
},
// `data` 是作为请求体被发送的数据
// 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
// 在没有设置 `transformRequest` 时,则必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属: FormData, File, Blob
// - Node 专属: Stream, Buffer
data: {
firstName: 'Fred'
},
// 发送请求体数据的可选语法
// 请求方式 post
// 只有 value 会被发送,key 则不会
data: 'Country=Brasil&City=Belo Horizonte',
// `timeout` 指定请求超时的毫秒数。
// 如果请求时间超过 `timeout` 的值,则请求会被中断
timeout: 1000, // 默认值是 `0` (永不超时)
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // default
// `adapter` 允许自定义处理请求,这使测试更加容易。
// 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
adapter: function (config) {
/* ... */
},
// `auth` HTTP Basic Auth
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` 表示浏览器将要响应的数据类型
// 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
// 浏览器专属:'blob'
responseType: 'json', // 默认值
// `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
// 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
// Note: Ignored for `responseType` of 'stream' or client-side requests
responseEncoding: 'utf8', // 默认值
// `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
xsrfCookieName: 'XSRF-TOKEN', // 默认值
// `xsrfHeaderName` 是带有 xsrf token 值的 http 请求头名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值
// `onUploadProgress` 允许为上传处理进度事件
// 浏览器专属
onUploadProgress: function (progressEvent) {
// 处理原生进度事件
},
// `onDownloadProgress` 允许为下载处理进度事件
// 浏览器专属
onDownloadProgress: function (progressEvent) {
// 处理原生进度事件
},
// `maxContentLength` 定义了 node.js 中允许的 HTTP 响应内容的最大字节数
maxContentLength: 2000,
// `maxBodyLength`(仅 Node)定义允许的 http 请求内容的最大字节数
maxBodyLength: 2000,
// `validateStatus` 定义了对于给定的 HTTP 状态码是 resolve 还是 reject promise。
// 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
// 则 promise 将会 resolved,否则是 rejected。
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认值
},
// `maxRedirects` 定义了在 node.js 中要遵循的最大重定向数。
// 如果设置为 0,则不会进行重定向
maxRedirects: 5, // 默认值
// `socketPath` 定义了在 node.js 中使用的 UNIX 套接字。
// e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
// 只能指定 `socketPath` 或 `proxy` 。
// 若都指定,这使用 `socketPath` 。
socketPath: null, // default
// `httpAgent` 和 `httpsAgent` 分别定义了在 node.js 中执行 http 和 https 请求时使用的自定义代理。
// 这允许添加诸如 `keepAlive` 之类的选项,这些选项在 Node.js v19.0.0 之前默认未启用。
// 在 Node.js v19.0.0 之后,不再需要自定义代理来启用 `keepAlive`,
// 因为 `http.globalAgent` 已经默认启用了 `keepAlive`。
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// `proxy` 定义了代理服务器的主机名,端口和协议。
// 您可以使用常规的 `http_proxy` 和 `https_proxy` 环境变量。
// 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
// `auth` 表示应使用 HTTP Basic auth 连接到代理,并且提供凭据。
// 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
// 如果代理服务器使用 HTTPS,则必须设置 protocol 为 `https`
proxy: {
protocol: 'https',
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// see https://axios-http.com/zh/docs/cancellation
cancelToken: new CancelToken(function (cancel) {
}),
// `decompress` indicates whether or not the response body should be decompressed
// automatically. If set to `true` will also remove the 'content-encoding' header
// from the responses objects of all decompressed responses
// - Node only (XHR cannot turn off decompression)
decompress: true // 默认值
}响应结构
一个请求的响应包含以下信息。
{
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 是服务器响应头
// 所有的 header 名称都是小写,而且可以使用方括号语法访问
// 例如: `response.headers['content-type']`
headers: {},
// `config` 是 `axios` 请求的配置信息
config: {},
// `request` 是生成此响应的请求
// 在 node.js 中它是最后一个 ClientRequest 实例 (in redirects),
// 在浏览器中则是 XMLHttpRequest 实例
request: {}
}默认配置
全局 axios 默认值
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';自定义实例默认值
// 创建实例时配置默认值
const instance = axios.create({
baseURL: 'https://api.example.com'
});
// 创建实例后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;配置的优先级
配置将会按优先级进行合并。它的顺序是:库默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后面的优先级要高于前面的。
// 使用库提供的默认配置创建实例
// 此时超时配置的默认值是 `0`
const instance = axios.create();
// 重写库的超时默认值
// 现在,所有使用此实例的请求都将等待 2.5 秒,然后才会超时
instance.defaults.timeout = 2500;
// 重写此请求的超时时间,因为该请求需要很长时间
instance.get('/longRequest', {
timeout: 5000
});拦截器
在请求或响应被 then 或 catch 处理前拦截它们。
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});如果稍后需要移除拦截器,可以这样:
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);可以给自定义的 axios 实例添加拦截器。
const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});错误处理
axios.get('/user/12345')
.catch(function (error) {
if (error.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// 请求已经成功发起,但没有收到响应
// `error.request` 在浏览器中是 XMLHttpRequest 的实例,
// 而在 node.js 中是 http.ClientRequest 的实例
console.log(error.request);
} else {
// 发送请求时出了点问题
console.log('Error', error.message);
}
console.log(error.config);
});使用 validateStatus 配置选项,可以自定义抛出错误的 HTTP code。
axios.get('/user/12345', {
validateStatus: function (status) {
return status < 500; // 处理状态码小于 500 的情况
}
})使用 toJSON 可以获取更多关于 HTTP 错误的信息。
axios.get('/user/12345')
.catch(function (error) {
console.log(error.toJSON());
});取消请求
AbortController
const controller = new AbortController();
axios.get('/foo/bar', {
signal: controller.signal
}).then(function(response) {
//...
});
// 取消请求
controller.abort()CancelToken deprecated
此 API 从 v0.22.0 开始已被弃用,不应在新项目中使用。
请求体编码
默认情况下,axios 将 JavaScript 对象序列化为 JSON 。 要以 application/x-www-form-urlencoded 格式发送数据,您可以使用以下选项之一。
浏览器
在浏览器中,可以使用URLSearchParams API,如下所示:
const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);请注意,不是所有的浏览器(参见 caniuse.com)都支持 URLSearchParams ,但是可以使用polyfill (确保 polyfill 全局环境)
或者, 您可以使用qs 库编码数据:
const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));或者用另一种方式 (ES6),
import qs from 'qs';
const data = { 'bar': 123 };
const options = {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: qs.stringify(data),
url,
};
axios(options);Node.js
Query string
在 node.js 中, 可以使用 querystring 模块,如下所示:
const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));或者从'url module'中使用'URLSearchParams',如下所示:
const url = require('url');
const params = new url.URLSearchParams({ foo: 'bar' });
axios.post('http://something.com/', params.toString());您也可以使用 qs 库。
注意:如果需要对嵌套对象进行字符串化处理,则最好使用 qs 库,因为 querystring 方法在该用例中存在已知问题(https://github.com/nodejs/node-v0.x-archive/issues/1665)。
Form data
在 node.js, 您可以使用 form-data 库,如下所示:
const FormData = require('form-data');
const form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
axios.post('https://example.com', form, { headers: form.getHeaders() })或者, 使用一个拦截器:
axios.interceptors.request.use(config => {
if (config.data instanceof FormData) {
Object.assign(config.headers, config.data.getHeaders());
}
return config;
});自动序列化
当请求头中的 content-type 是 application/x-www-form-urlencoded 时,Axios 将自动地将普通对象序列化成 urlencoded 的格式。
在浏览器和 node.js 环境中都适用:
const data = {
x: 1,
arr: [1, 2, 3],
arr2: [1, [2], 3],
users: [{name: 'Peter', surname: 'Griffin'}, {name: 'Thomas', surname: 'Anderson'}],
};
await axios.post('https://postman-echo.com/post', data,
{headers: {'content-type': 'application/x-www-form-urlencoded'}}
);服务器接收到的数据就像是这样:
{
x: '1',
'arr[]': [ '1', '2', '3' ],
'arr2[0]': '1',
'arr2[1][0]': '2',
'arr2[2]': '3',
'arr3[]': [ '1', '2', '3' ],
'users[0][name]': 'Peter',
'users[0][surname]': 'griffin',
'users[1][name]': 'Thomas',
'users[1][surname]': 'Anderson'
}如果您的服务器框架的请求体解析器(例如express.js的body-parser)支持嵌套对象解码,则其接收到的数据将与您提交的数据一样。
以下是一个express.js的服务器示例,它将会把接收到的数据作为响应返回:
var app = express();
app.use(bodyParser.urlencoded({ extended: true })); // support url-encoded bodies
app.post('/', function (req, res, next) {
res.send(JSON.stringify(req.body));
});
server = app.listen(3000);