企业开发网站建设哪家好,网站建设推广工资,建筑工程网名大全,永久免费云linux服务器网页Axios
Axios是一个基于Promise的HTTP库#xff0c;可以发送get、post等请求#xff0c;它作用于浏览器和Node.js中。当运行在浏览器时#xff0c;使用XMLHttpRequest接口发送请求#xff1b;当运行在Node.js时#xff0c;使用HTTP对象发送请求。 使用步骤#xff1a; 第…
Axios
Axios是一个基于Promise的HTTP库可以发送get、post等请求它作用于浏览器和Node.js中。当运行在浏览器时使用XMLHttpRequest接口发送请求当运行在Node.js时使用HTTP对象发送请求。 使用步骤 第一步安装axios 略 第二步在项目中使用Axios时通常的做法是先将Axios封装成一个模块然后在组件中导入模块。 第三步编写各种请求 这里只说明 基本的get请求和post请求。
request({url: 请求路径,method: get,params: { 参数 }
}).then(res {console.log(res)
}).catch(error {console.log(error)
})get请求
/*** 发送GET请求*/
export const getReq (url, params) {return axios({method: get,params, // 使用params而非dataurl: ${base}${url},headers: {token: localStorage.getItem(token),}});
} 使用它
// 获取用户列表带分页参数
getReq(/api/users, { page: 1, pageSize: 10 }).then(res {console.log(用户列表:, res.data);}).catch(err {console.error(请求失败:, err);}); post请求
request({url: 请求路径,method: post,data: { 参数 }
}).then(res {console.log(res)
}).catch(error {console.log(error)
})export const postReq (url, params) {return axios({method: post,url: ${base}${url},data: params,headers: {token: localStorage.getItem(token),}}); 异步请求调用中 asyncawait 的应用
代码
export const fetchData async (url, params) {try {const response await axios({method: get,params, // 修正使用 params 而非 dataurl: ${base}${url},headers: {token: localStorage.getItem(token),}});return response.data;} catch (error) {console.error(请求失败:, error);throw error; // 修正重新抛出错误让调用者处理}
}; asyncawait 的概念
async/await 是一种建立在Promise之上的编写异步或非阻塞代码的新方法。async 是异步的意思而 await 是 async wait的简写即异步等待。
所以从语义上就很好理解 async 用于声明一个 函数 是异步的而await 用于等待一个异步方法执行完成。
那么想要同步使用数据的话就可以使用 asyncawait 。 说明async函数返回的是一个 Promise 对象。async 函数包含函数语句、函数表达式、Lambda表达式会返回一个 Promise 对象如果在函数中 一个直接量async 会把这个直接量通过promise.solve() 封装成 Promise 对象。
如果 async 函数没有返回值 它会返回 promise.solve(underfined)。
await 等待的是一个表达式这个表达式的计算结果是 Promise 对象或者其它值换句话说await 可以等任意表达式的结果。
如果它等到的不是一个 Promise 对象那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象await 就忙起来了它会阻塞后面的代码等着 Promise 对象 resolve然后得到 resolve 的值作为 await 表达式的运算结果。
调用方式
Promise 链式调用.then().catch() 同步风格的
await在 async 函数内部使用 romise 链式调用适合 “非阻塞、并行、兼容旧环境” 的场景强调异步操作的独立性。async/await适合 “顺序依赖、复杂流程、高可读性” 的场景让异步代码更接近同步思维模式。
1. 使用 .then() 和 .catch() 链式调用
import { fetchData } from ./api; // 假设从 api.js 导入// 调用 fetchData 获取用户列表
fetchData(/api/users, { page: 1, pageSize: 10 }).then(data {console.log(用户列表:, data);// 处理返回的数据如更新组件状态}).catch(error {console.error(请求失败:, error);// 显示错误消息如弹框提示});
//其他逻辑会和fetchData同步进行
..... 2. 在 async 函数内部使用 await
async function loadUsers() {try {// 等待请求完成并获取数据const data await fetchData(/api/users, { page: 1, pageSize: 10 });console.log(用户列表:, data);// 可以直接使用同步风格的代码处理数据const firstUser data.list[0];console.log(第一个用户:, firstUser);} catch (error) {console.error(请求失败:, error);// 错误处理逻辑}
}// 调用 async 函数
loadUsers();当执行 loadUsers() 函数时它会返回一个 Promise 对象并且其内部逻辑会以异步方式执行。以下是详细解释
1. 函数返回值Promise 对象 原因任何使用 async 关键字声明的函数都会自动返回一个 Promise。 示例验证 javascript const result loadUsers();
console.log(result instanceof Promise); // 输出: truePromise 的状态 成功fulfilled当 fetchData 请求成功且没有抛出异常时Promise 会 resolve并传递 loadUsers 函数的返回值若没有显式返回默认返回 undefined。失败rejected当 fetchData 抛出异常或 loadUsers 内部 try 块中的代码报错时Promise 会 reject并传递错误对象。
2. 函数执行流程异步本质
javascript
console.log(开始执行);
loadUsers();
console.log(结束执行);// 输出顺序
// 开始执行
// 结束执行
// 等待 fetchData 请求完成后
// 用户列表: ...
// 第一个用户: ...关键特点 loadUsers() 函数被调用后立即返回 Promise不会阻塞后续代码执行。await fetchData(...) 仅暂停函数内部的执行不会影响外部代码如 console.log(结束执行) 会先于 fetchData 的结果输出。当 fetchData 的 Promise 解决成功 / 失败时loadUsers 内部的 await 会恢复执行并决定 Promise 的最终状态。
3. Promise 的解决resolve情况
当 fetchData 请求成功且 try 块内代码无异常时 loadUsers 的 Promise 会 resolve返回值为 undefined因为函数没有显式 return。 等价于 javascript async function loadUsers() {// ... 代码 ...return undefined; // 隐式返回
}可通过 .then() 捕获结果 javascript loadUsers().then(result {console.log(loadUsers 返回值:, result); // 输出: undefined
});4. Promise 的拒绝reject情况
当出现以下情况时loadUsers 的 Promise 会 reject fetchData 抛出错误 javascript fetchData(/api/users, { page: 1 }).catch(error {throw new Error(请求失败: error); // 被 loadUsers 的 catch 捕获});try 块内其他代码报错 javascript const firstUser data.list[0]; // 若 data.list 为 undefined会抛出 TypeErrorcatch 块中重新抛出错误 javascript catch (error) {console.error(请求失败:, error);throw error; // 重新抛出导致 Promise reject
}可通过 .catch() 捕获错误 javascript loadUsers().catch(error {console.error(loadUsers 错误:, error);
});5. 与 Promise 链式调用的等价关系
loadUsers 函数的异步逻辑等价于以下 Promise 写法 javascript
function loadUsers() {return fetchData(/api/users, { page: 1, pageSize: 10 }).then(data {console.log(用户列表:, data);const firstUser data.list[0];console.log(第一个用户:, firstUser);// 隐式返回 undefined}).catch(error {console.error(请求失败:, error);throw error; // 重新抛出错误保持 Promise 链的异常传递});
}6. 如何获取函数的执行结果
1使用 .then()
javascript
loadUsers().then(() {console.log(数据处理完成);}).catch(error {console.error(处理失败:, error);});2在另一个 async 函数中使用 await
javascript
async function processData() {try {await loadUsers(); // 等待 loadUsers 的 Promise 解决console.log(loadUsers 执行完毕);} catch (error) {console.error(processData 捕获到错误:, error);}
}返回值loadUsers() 始终返回一个 Promise 对象。状态由内部逻辑决定 成功时fetchData 正常返回且无代码错误Promise resolve返回 undefined。失败时fetchData 报错或代码异常Promise reject传递错误对象。 异步本质函数内部使用 await 暂仅停自身执行不阻塞主线程整体仍为异步操作。
应用transformRequest
export const postRequest (url, params) {return axios({method: post,url: ${base}${url},data: params,transformRequest: [function (data) {let ret ;for (let key in data) {ret encodeURIComponent(key) encodeURIComponent(data[key]) ;}return ret;}],headers: {Content-Type: application/x-www-form-urlencoded, // 修正为表单格式}});
}
说明 数据格式与请求头的关系 application/json请求体应为 JSON 格式如{key: value}。application/x-www-form-urlencoded请求体应为表单格式如keyvaluekey2value2。 transformRequest的影响 当前代码将对象转换为表单格式数据但请求头却声明为 JSON导致后端可能无法解析。若后端期望 JSON 数据应移除transformRequest并保持application/json头。 正确的搭配方式 数据格式Content-Type是否需要 transformRequestJSONapplication/json不需要表单数据application/x-www-form-urlencoded需要如当前函数二进制文件 / 表单multipart/form-data不需要
函数调用示例
场景 1提交表单数据到后端 import { postRequest } from ./api.js; // 导入函数// 表单数据
const formData {username: test_user,password: 123456,email: testexample.com
};// 调用函数
postRequest(/api/register, formData).then(response {console.log(注册成功:, response.data);}).catch(error {console.error(注册失败:, error);});场景 2发送 JSON 数据需修改函数
如果需要发送 JSON 数据应使用以下封装 export const postJsonRequest (url, params) {return axios({method: post,url: ${base}${url},data: params,headers: {Content-Type: application/json,}});
}// 调用示例
const userData {name: 张三,age: 25,hobbies: [阅读, 编程]
};postJsonRequest(/api/users, userData).then(res console.log(res.data));调用注意事项 参数说明 urlAPI 路径如/api/login会自动拼接base如http://localhost:8080。params需要发送的数据对象会被transformRequest转换为表单格式。 错误处理 在调用时添加.catch()处理请求失败 postRequest(...).catch(error {const status error.response?.status || 网络错误;const message error.response?.data?.message || 请求失败;console.error(状态码 ${status}: ${message});
});与其他请求函数的区别 若后端接口需要不同的 Content-Type应创建不同的封装函数如 JSON 格式、文件上传等。 数据为对象格式如{key: value}后端接口期望表单数据application/x-www-form-urlencoded添加错误处理逻辑以应对请求失败的情况 如果需要发送 JSON 数据最好创建专门的函数不需要transformRequest。 对不同格式的数据spring boot 端的处理 场景推荐注解示例处理 JSON 数据RequestBodyRequestBody User user处理简单表单数据少量参数RequestParamRequestParam(username) String name处理复杂表单数据对象绑定ModelAttributeModelAttribute User user同时支持 JSON 和表单需自定义RequestBody 转换器配置 FormHttpMessageConverter
建议 JSON统一使用 RequestBody前端发送 application/json。表单使用 RequestParam 或 ModelAttribute前端发送 application/x-www-form-urlencoded。避免混用不要试图用 RequestBody 同时处理两种格式会增加复杂度。 postJsonRequest
export const postJsonRequest (url, params) {return axios({method: post,url: ${base}${url},data: params, // axios 自动将对象序列化为 JSONheaders: {Content-Type: application/json,}});
} 调用方式例子
// 发送用户数据
const userData {username: john,email: johnexample.com,isActive: true
};postJsonRequest(/api/users, userData).then(res console.log(用户创建成功:, res.data)).catch(err console.error(错误:, err)); 发送表单数据application/x-www-form-urlencoded
export const postFormRequest (url, params) {return axios({method: post,url: ${base}${url},data: params,transformRequest: [function (data) {let ret ;for (let key in data) {ret encodeURIComponent(key) encodeURIComponent(data[key]) ;}return ret;}],headers: {Content-Type: application/x-www-form-urlencoded,}});
} 调用方式例子
// 提交登录表单
const loginData {username: admin,password: 123456,rememberMe: true
};postFormRequest(/api/login, loginData).then(res {localStorage.setItem(token, res.data.token);console.log(登录成功);}).catch(err alert(登录失败: err.message)); 比与适用场景及编码问题
方案Content-Type数据格式后端适配前端写法方案一JSONapplication/json{key:value}Spring Boot 的 RequestBody直接传递对象方案二表单application/x-www-form-urlencodedkeyvaluekey2value2Spring Boot 的 RequestParam/ModelAttribute需手动或用库序列化 后端接口匹配 JSON 格式确保后端使用 RequestBody 注解表单格式确保后端使用 RequestParam 或 ModelAttribute 编码问题 表单数据中的特殊字符如中文会被 encodeURIComponent 自动编码JSON 数据中的中文会被序列化为 Unicode 字符如 \u4e2d
putRequest
export const putRequest (url, params) {return axios({method: put,url: ${base}${url},data: params,transformRequest: [function (data) {if (!data) return ;const ret [];for (let key in data) {if (data.hasOwnProperty(key)) {const value data[key];// 处理值为 null 或 undefined 的情况const encodedValue value null || value undefined ? : encodeURIComponent(value);ret.push(${encodeURIComponent(key)}${encodedValue});}}// 使用 join 避免末尾多余的 return ret.join();}],headers: {Content-Type: application/x-www-form-urlencoded}}).catch(error {console.error(PUT 请求失败:, error);// 可以在这里进行统一的错误处理throw error; // 继续抛出错误让调用者可以捕获});
}; 参考vueelement UI 学习总结笔记(一)_vueelementui一点-CSDN博客