axios 在 CommonJS 环境下的实战用法:require 导入、then/catch/finally 与 async/await 深度解析

发布时间:2026/9/7 4:28:27
axios 在 CommonJS 环境下的实战用法:require 导入、then/catch/finally 与 async/await 深度解析 axios 在 CommonJS 环境下的实战用法require 导入、then/catch/finally 与 async/await 深度解析【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios本篇以 axios 官方文档的 CommonJS 示例页为主线系统讲解在 Node.js 及构建工具环境下如何导入 axios、如何用then/catch/finally与async/await两种方式处理 GET、POST、PUT、PATCH、DELETE 五类请求并结合仓库源码说明require只暴露默认导出的机制、请求 Promise 的产生位置以及 resolve/reject 的判定规则帮助读者从会写示例进阶到看懂底层。一、在 CommonJS 环境导入 axiosaxios 官方文档将 JavaScript 环境的导入方式分为两类不使用打包器的纯 CommonJS 环境以及使用打包器的 ES Module 写法。1.1 无打包器require在 Node.js 这类 CommonJS 环境中使用require函数导入const axios require(axios);这一行的实际解析逻辑由 package.json 中的字段决定main字段指向./dist/node/axios.cjs即 Node 端预构建的 CommonJS 产物exports[.].default.require同样映射到./dist/node/axios.cjs而exports[.].browser.require则映射到./dist/browser/axios.cjs——也就是说同一句require(axios)在打包器把环境标记为browser时会拿到浏览器版 CJS 包在 Node 中拿到 Node 版 CJS 包exports[.].types.require指向./index.d.cts保证 CommonJS 场景下也能拿到对应的 TypeScript 类型声明。1.2 有打包器webpack、rollup、vite 等在使用打包器的环境中可以直接写 ES Module 的import语句import axios from axios;打包器会走exports[.].default.default即 index.js 这个 ESM 入口。该入口把 lib/axios.js 的默认导出解包为一组命名导出Axios、AxiosError、isCancel、toFormData、HttpStatusCode等因此import axios, { isCancel, AxiosError } from axios这类命名导入只在 ES Module 侧可用。1.3 为什么 require 只能用默认导出从源码结构看这是有意为之的设计。lib/axios.js 文件末尾有如下代码axios.default axios; // this module should only have a default export export default axios;库把Axios类、AxiosError、CanceledError、isCancel、VERSION、toFormData、spread、mergeConfig、AxiosHeaders、HttpStatusCode、formToJSON、getAdapter等全部挂载为默认导出对象axios的静态属性见 lib/axios.js。因此 CommonJS 下只能拿到默认导出这一个入口但所有工具函数都挂在它上面const axios require(axios); console.log(axios.isCancel(something)); // false官方文档 first-steps.md 对此有明确说明If you userequirefor importing, only the default export is available。1.4 两种特殊导入写法对于部分打包器和 ES6 linter可能需要显式指定 default 绑定import { default as axios } from axios;对于模块解析行为异常的定制或遗留环境可以绕过包解析直接引入预构建产物package.json 的exports中显式声明了这两个子路径const axios require(axios/dist/browser/axios.cjs); // 浏览器 CommonJS 产物ES2017 // const axios require(axios/dist/node/axios.cjs); // Node CommonJS 产物ES2017二、Promise 方式then / catch / finallyaxios 的核心返回类型是 Promise因此可以选择使用then、catch、finally回调来处理响应数据、错误和完成通知。以下示例均直接继承自官方文档 commonjs.md目标接口为 JSONPlaceholder 测试 API。2.1 GET 请求axios .get(https://jsonplaceholder.typicode.com/posts, { params: { postId: 5, }, }) .then((response) { console.log(response.data); }) .catch((error) { console.error(error); }) .finally(() { console.log(Request completed); });params会由buildURL序列化后拼接到查询字符串上最终 URL 形如?postId5。2.2 POST 请求axios .post(https://jsonplaceholder.typicode.com/posts, { title: foo, body: bar, userId: 1, }) .then((response) { console.log(response.data); }) .catch((error) { console.error(error); }) .finally(() { console.log(Request completed); });2.3 PUT 请求axios .put(https://jsonplaceholder.typicode.com/posts/1, { title: foo, body: bar, userId: 1, }) .then((response) { console.log(response.data); }) .catch((error) { console.error(error); }) .finally(() { console.log(Request completed); });2.4 PATCH 请求axios .patch(https://jsonplaceholder.typicode.com/posts/1, { title: foo, }) .then((response) { console.log(response.data); }) .catch((error) { console.error(error); }) .finally(() { console.log(Request completed); });2.5 DELETE 请求axios .delete(https://jsonplaceholder.typicode.com/posts/1) .then((response) { console.log(response.data); }) .catch((error) { console.error(error); }) .finally(() { console.log(Request completed); });2.6 源码视角这些方法返回的 Promise 从哪来上面五种方法之所以都能统一返回 Promise根源在 lib/core/Axios.js 中的别名生成逻辑// 无请求体的方法delete / get / head / options utils.forEach([delete, get, head, options], function forEachMethodNoData(method) { Axios.prototype[method] function (url, config) { return this.request(mergeConfig(config || {}, { method, url, ... })); }; }); // 有请求体的方法post / put / patch / query utils.forEach([post, put, patch, query], function forEachMethodWithData(method) { ... Axios.prototype[method] generateHTTPMethod(); });也就是说axios.get、axios.post等并不各自独立实现请求逻辑而是把method、url、data合并进配置后统一委托给Axios.prototype.request。而request方法在请求拦截器链执行完毕后调用dispatchRequest发出真实请求再把 Promise 依次挂上响应拦截器链并返回见 lib/core/Axios.jsif (!promise) { try { promise dispatchRequest.call(this, newConfig); } catch (error) { promise Promise.reject(error); } } // 依次串联响应拦截器后 return promise;这也解释了无论同步抛错还是异步失败调用方拿到的始终是一个可.then/.catch的 Promisethen/catch/finally的写法因此对所有请求方法普适。2.7 resolve 还是 rejectsettle 的判定规则Promise 最终 resolve 出完整的response含response.data还是 reject 出一个AxiosError由 lib/core/settle.js 决定const validateStatus response.config.validateStatus; if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); } else { reject(new AxiosError( Request failed with status code response.status, response.status 400 response.status 500 ? AxiosError.ERR_BAD_REQUEST : AxiosError.ERR_BAD_RESPONSE, ... )); }默认validateStatus只放行 2xx 状态码状态码在 200299 之间时走then分支response.data即为解析后的响应体4xx 状态码 reject 出错误码为ERR_BAD_REQUEST的AxiosError5xx 则 reject 出ERR_BAD_RESPONSE——这正是示例中.catch((error) ...)能接住 HTTP 错误的底层原因。更完整的错误码与处理策略可参考 error-handling.md请求配置如timeout、validateStatus见 request-config.md。三、async / await 方式处理 Promise 的另一种方式是asyncawait它允许使用try/catch/finally块来处理错误与完成代码更线性、可读性更好也能避免回调嵌套callback hell。注意async/await属于 ECMAScript 2017 语法Internet Explorer 及更老浏览器不支持请谨慎使用原文档提示。在 Node.js 环境这一限制不适用但在面向旧浏览器的 CJS 产物中需自行 polyfill 或降级为then写法。3.1 GET 请求const getPosts async () { try { const response await axios.get( https://jsonplaceholder.typicode.com/posts, { params: { postId: 5, }, } ); console.log(response.data); } catch (error) { console.error(error); } finally { console.log(Request completed); } };3.2 POST 请求const createPost async () { try { const response await axios.post( https://jsonplaceholder.typicode.com/posts, { title: foo, body: bar, userId: 1, } ); console.log(response.data); } catch (error) { console.error(error); } finally { console.log(Request completed); } };3.3 PUT 请求const updatePost async () { try { const response await axios.put( https://jsonplaceholder.typicode.com/posts/1, { title: foo, body: bar, userId: 1, } ); console.log(response.data); } catch (error) { console.error(error); } finally { console.log(Request completed); } };3.4 PATCH 请求const updatePost async () { try { const response await axios.patch( https://jsonplaceholder.typicode.com/posts/1, { title: foo, } ); console.log(response.data); } catch (error) { console.error(error); } finally { console.log(Request completed); } };3.5 DELETE 请求const deletePost async () { try { const response await axios.delete( https://jsonplaceholder.typicode.com/posts/1 ); console.log(response.data); } catch (error) { console.error(error); } finally { console.log(Request completed); } };3.6 两种写法的取舍then/catch/finally兼容性最好任何支持 Promise 的环境Node 与老式打包配置都能运行缺点是多个请求串接时链式嵌套会变深async/await控制流与同步代码一致try/catch统一捕获适合业务函数封装如getPosts、createPost这样的命名异步函数。需要目标环境或打包工具支持 ES2017 语法。四、测试佐证CJS 冒烟测试如何验证上述行为仓库自带针对 CommonJS 产物的冒烟测试直接require(axios)后逐一验证各请求方法别名可作为上面示例行为的官方回归依据tests/smoke/cjs/tests/basic.smoke.test.cjs 通过一个 mock transport 捕获实际发出的请求断言axios.get(...)对应method GET、axios.post(...)对应POST并覆盖了put、patch、delete、head、options以及最简的axios(url, config)调用形式该测试文件运行在独立的工作包 tests/smoke/cjs/package.json 中对应根目录 package.json 里的test:smoke:cjs:vitest脚本验证的是发布产物distCJS 包而非源码与本文无打包器直接require的场景完全一致。五、小结与延伸阅读本文覆盖了 CommonJS 场景下 axios 的完整使用链路require导入含打包器与dist产物的三种变体→ 五种请求方法的then/catch/finally写法 →async/await等价写法并在源码层面确认了require只能拿到默认导出工具函数全部挂载在其静态属性上lib/axios.js各 HTTP 方法别名最终都收敛到Axios.prototype.request并返回 Promiselib/core/Axios.jsPromise 的 resolve/reject 由validateStatus与状态码区间共同决定lib/core/settle.js。如需继续深入可参考仓库中的 first-steps.md安装与首次请求、request-config.md完整请求配置项、error-handling.md错误处理以及 api-reference.mdAPI 参考。【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考