赞
踩
上古浏览器页面在向服务器请求数据时,因为返回的是整个页面的数据,页面都会强制刷新一下,这对于用户来讲并不是很友好。并且我们只是需要修改页面的部分数据,但是从服务器端发送的却是整个页面的数据,十分消耗网络资源。而我们只是需要修改页面的部分数据,也希望不刷新页面,因此异步网络请求就应运而生。
Ajax(Asynchronous JavaScript and XML):异步网络请求。Ajax能够让页面无刷新的请求数据。
实现ajax的方式有多种,如jQuery封装的ajax,原生的XMLHttpRequest,以及axios。但各种方式都有利弊
原生的XMLHttpRequest的配置和调用方式都很繁琐,实现异步请求十分麻烦
jQuery的ajax相对于原生的ajax是非常好用的,但是没有必要因为要用ajax异步网络请求而引用jQuery框架
pnpm i axios --save-dev
在项目中创建untils/request.js文件
- import axios from 'axios'
-
- // 创建可一个新的axios对象
- const request = axios.create({
- baseURL: 'http://localhost:9090', // 后端的接口地址 ip:port
- timeout: 30000
- })
-
- // request 拦截器
- // 可以自请求发送前对请求做一些处理
- // 比如统一加token,对请求参数统一加密
- request.interceptors.request.use(config => {
- config.headers['Content-Type'] = 'application/json;charset=utf-8';
- // let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null
- // config.headers['token'] = 'token' // 设置请求头
-
- return config
- }, error => {
- console.error('request error: ' + error) // for debug
- return Promise.reject(error)
- });
-
- // response 拦截器
- // 可以在接口响应后统一处理结果
- request.interceptors.response.use(
- response => {
- let res = response.data;
-
- // 兼容服务端返回的字符串数据
- if (typeof res === 'string') {
- res = res ? JSON.parse(res) : res
- }
- return res;
- },
- error => {
- console.error('response error: ' + error) // for debug
- return Promise.reject(error)
- }
- )
-
-
- export default request
- import axios from "axios";
-
- data() {
- return {
- users: []
- }
- }
-
- mounted() { // 页面加载完成之后触发
- axios.get('http://localhost:9090/user/selectAll').then(res => {
- console.log(res.data) // 后台返回的数据
- // res.data = { // 数据格式
- // code: '200',
- // msg: '请求成功',
- // data: {
- //
- // }
- // }
- })
- },
@CrossOrigin
随着富客户端快速发展,普通本地存储(cookie)无法满足前端需要的大量数据的存储需求 HTML5,引入Web存储,Web应用程序可以在用户的浏览器中本地存储数据
- 包括本地数据库技术 IndexedDB/WebSQL等
- 包括基于键值对 LocalStorage/SessionStorage
Web Storage提供了两种在客户端存储数据的方式,即**LocalStorage和SessionStorage**,它们都用于以键值对的形式保存数据。具体如下:
- LocalStorage,本地全局数据存储。永久性数据,需手动删除,无加密,可跨域调用
- SessionStorage,当前页面标签存储。仅与当前页面绑定,标签/浏览器关闭,数据自动销毁
发出请求的地址与目标地址,域名(IP)+端口一致,即为,同源 浏览器持有用户大量敏感数据。因此,同源安全策略,即限制跨域请求(尤其基于Ajax发出的请求),是浏览器的一种安全机制
方法1,前端同时需要修改axios全局请求的基本地址。无需vue配置 方法1,不利于开发环境与生产环境间的切换
此方法仅在开发测试环境下有效
axios可以请求的方法:
- get:获取数据,请求指定的信息,返回实体对象
- post:向指定资源提交数据(例如表单提交或文件上传)
- put:更新数据,从客户端向服务器传送的数据取代指定的文档的内容
- patch:更新数据,是对put方法的补充,用来对已知资源进行局部更新
- delete:请求服务器删除指定的数据
方式一:请求别名的使用
axios.get(url[, config]) 用于获取数据
- <script setup>
- import { onMounted } from 'vue';
- import axios from 'axios';
-
- const fetchData = async () => {
- try {
- const response = await axios.get('/data.json');
- console.log('数据:', response);
- console.log('真正的数据:', response.data);
- } catch (error) {
- console.error(error);
- }
- };
-
- onMounted(() => {
- fetchData();
- });
- </script>
- <script setup>
- import axios from 'axios';
-
- // 第一种方式:将参数直接写在 URL 中
- async function fetchUserByIdInUrl() {
- try {
- const response = await axios.get("/data.json?id=5");
- console.log("数据(URL 直接携带参数):", response.data);
- } catch (error) {
- console.error("错误(URL 直接携带参数):", error);
- }
- }
-
- // 第二种方式:将参数写在 params 对象中
- async function fetchUserByIdInParams() {
- try {
- const response = await axios.get("/data.json", {
- params: {
- id: 5,
- },
- });
- console.log("数据(params 对象传递参数):", response.data);
- } catch (error) {
- console.error("错误(params 对象传递参数):", error);
- }
- }
-
- // 使用 async/await
- async function fetchUserWithAsyncAwait() {
- try {
- const response = await axios.get("/user?ID=12345");
- console.log("数据(async/await):", response.data);
- } catch (error) {
- console.error("错误(async/await):", error);
- }
- }
-
- // 在组件挂载后执行请求
- onMounted(() => {
- fetchUserByIdInUrl();
- fetchUserByIdInParams();
- fetchUserWithAsyncAwait();
- });
- </script>
此时表示,参数为id=5,最终的请求路径Request URL:http://localhost:8080/data.json?id=5
方式二: 通过向axios传递相关配置来创建请求
- <script setup>
- import axios from 'axios';
-
- async function fetchData() {
- try {
- const response = await axios({
- method: "get",
- url: "/data.json"
- });
- console.log("数据:", response.data);
- } catch (error) {
- console.error("错误:", error);
- }
- }
-
- onMounted(() => {
- fetchData();
- });
- </script>
如果带有参数,代码如下
- <script setup>
- import axios from 'axios';
-
- async function fetchData() {
- try {
- const response = await axios({
- method: "get",
- url: "/data.json",
- params: {
- id: 5,
- },
- });
- console.log("数据:", response.data);
- } catch (error) {
- console.error("错误:", error);
- }
- }
-
- onMounted(() => {
- fetchData();
- });
- </script>
此时表示,参数为id=5,最终的请求路径Request URL:http://localhost:8080/data.json?id=5
总结
get请求时,参数会以url string 的形式进行传递,即?后的字符串则为其请求参数,并以&做为分隔符。
post请求常用的数据请求格式有三种:
- Content-Type : application/x-www-form-urlencoded。ajax默认的数据格式。请求体中的数据会以json字符串的形式发送到后端。
- Content-Type : application/json ; charset=utf-8。axios默认的数据格式。请求体中的数据会以普通表单形式(键值对)发送到后端。
- Content-Type : multipart/form-data 。它会将请求体的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。
- <script setup>
- import axios from 'axios';
- import qs from 'qs';
-
- async function sendData() {
- const data = { uname: "dingding", upwd: "123456" };
-
- try {
- const response = await axios.post("/date.json", qs.stringify({ data }));
- console.log("响应:", response);
- } catch (error) {
- console.error("错误:", error);
- }
- }
-
- onMounted(() => {
- sendData();
- });
- </script>
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于发送数据
- async function sendData() {
- // 创建所需发送的数据对象
- const data = { uname: "dingding", upwd: 123456 };
-
- // 创建一个 FormData 对象用于存储要发送的数据
- const formData = new FormData();
-
- // 遍历数据对象的属性,将它们添加到 FormData 对象中
- for (const key in data) {
- formData.append(key, data[key]);
- }
-
- // 打印 FormData 对象,便于调试
- console.log(formData);
-
- try {
- // 使用 Axios 发起 POST 请求,将 FormData 对象作为请求体
- const response = await axios.post("/date.json", formData);
- // 打印请求的响应数据
- console.log("响应数据:", response.data);
- } catch (error) {
- // 处理可能出现的错误
- console.error("请求错误:", error);
- }
- }
-
- // 在组件挂载后调用 sendData 函数,确保数据被发送
- onMounted(() => {
- sendData();
- });
- </script>
注意:form-data类型的相关请求信息
- 请求地址Request URL: http://localhost:8080/data.json
- 请求头中Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySmuEKOlBaxhc0In2
- 参数形式:{uname: "dingding", upwd: 123456}
axios.post(url[, data[, config]]) 用于发送数据 `data`对象是作为请求主体被发送的数据
axios发送post无参请求,代码如下:
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于发送 POST 请求
- async function sendPostRequest() {
- try {
- // 使用 Axios 发起 POST 请求,没有请求体
- const response = await axios.post("/data.json");
- // 打印请求的响应结果
- console.log("响应:", response);
- } catch (error) {
- // 处理可能出现的错误
- console.error("请求错误:", error);
- }
- }
-
- // 在组件挂载后调用 sendPostRequest 函数,确保请求被发送
- onMounted(() => {
- sendPostRequest();
- });
- </script>
axios发送post有参请求,2种传参形式,代码如下:
① 查询字符串形式
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于发送 POST 请求并携带参数
- async function sendPostRequestWithParams() {
- try {
- // 使用 Axios 发起 POST 请求,请求路径为 "/data.json",请求体为查询字符串 "uname=dingding&upwd=123456"
- const response = await axios.post("/data.json", "uname=dingding&upwd=123456");
- // 打印请求的响应结果
- console.log("响应:", response);
- } catch (error) {
- // 处理可能出现的错误
- console.error("请求错误:", error);
- }
- }
-
- // 在组件挂载后调用 sendPostRequestWithParams 函数,确保请求被发送
- onMounted(() => {
- sendPostRequestWithParams();
- });
- </script>
② 对象形式
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于发送 POST 请求并携带参数
- async function sendPostRequestWithJsonParams() {
- try {
- // 使用 Axios 发起 POST 请求,请求路径为 "/data.json",请求体为 JSON 对象 {uname: "dingding", upwd: 123456}
- const response = await axios.post("/data.json", { uname: "dingding", upwd: 123456 });
- // 打印请求的响应结果
- console.log("响应:", response);
- } catch (error) {
- // 处理可能出现的错误
- console.error("请求错误:", error);
- }
- }
-
- // 在组件挂载后调用 sendPostRequestWithJsonParams 函数,确保请求被发送
- onMounted(() => {
- sendPostRequestWithJsonParams();
- });
- </script>
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于发送 POST 请求并携带参数
- async function sendPostRequestWithParams() {
- const data = { uname: "dingding", upwd: 123456 };
-
- try {
- // 使用 Axios 发起 POST 请求,请求路径为 "/data.json",请求体为 JSON 对象 {uname: "dingding", upwd: 123456}
- const response = await axios.post("/data.json", data);
- // 打印请求的响应结果
- console.log("响应:", response);
- } catch (error) {
- // 处理可能出现的错误
- console.error("请求错误:", error);
- }
- }
-
- // 在组件挂载后调用 sendPostRequestWithParams 函数,确保请求被发送
- onMounted(() => {
- sendPostRequestWithParams();
- });
- </script>
put和patch请求与post请求用法一样类似,同样有x-www-form-urlencoded、applicition/json和form-data,只有method不同,其他相同。在此不过多赘述了,简单写一下!
-
-
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于发送 PUT 请求并携带参数
- async function sendPutRequestWithParams() {
- const data = { uname: "dingding", upwd: 123456 };
-
- try {
- // 使用 Axios 发起 PUT 请求,请求路径为 "/data.json",请求体为 JSON 对象 {uname: "dingding", upwd: 123456}
- const putResponse = await axios.put("/data.json", data);
- // 打印 PUT 请求的响应结果
- console.log("PUT 响应:", putResponse);
- } catch (error) {
- // 处理可能出现的错误
- console.error("PUT 请求错误:", error);
- }
- }
-
- // 定义一个异步函数,用于发送 PATCH 请求并携带参数
- async function sendPatchRequestWithParams() {
- const data = { uname: "dingding", upwd: 123456 };
-
- try {
- // 使用 Axios 发起 PATCH 请求,请求路径为 "/data.json",请求体为 JSON 对象 {uname: "dingding", upwd: 123456}
- const patchResponse = await axios.patch("/data.json", data);
- // 打印 PATCH 请求的响应结果
- console.log("PATCH 响应:", patchResponse);
- } catch (error) {
- // 处理可能出现的错误
- console.error("PATCH 请求错误:", error);
- }
- }
-
- // 在组件挂载后分别调用 sendPutRequestWithParams 和 sendPatchRequestWithParams 函数,确保请求被发送
- onMounted(() => {
- sendPutRequestWithParams();
- sendPatchRequestWithParams();
- });
- </script>
axios.delete(url[, config])与axios.get(url[, config])用法基本相似,但是作用不同,它用于删除数据,同get方法一样也可以有几种写法 。
delete请求有时候需要把参数拼接到URL上,有时候像post请求那样把参数放在请求体里面。至于具体怎么调用,需要和后端商量好!
- <script setup>
- import axios from 'axios';
-
- // 使用别名法:DELETE 请求携带 params 参数
- async function sendDeleteRequestWithParams() {
- try {
- // 1. 通过 params 对象传递参数
- await axios.delete("/data.json", {
- params: {
- id: 12,
- },
- }).then((res) => {
- console.log(res, "delete (params object)");
- });
-
- // 2. 通过查询字符串形式传递参数
- await axios.delete("/data.json?id=2", {
- params: {
- id: 12,
- },
- }).then((res) => {
- console.log(res, "delete (query string)");
- });
- } catch (error) {
- console.error("DELETE 请求错误:", error);
- }
- }
-
- // 不使用别名法:通过传递相关配置创建 DELETE 请求
- async function sendDeleteRequestWithConfig() {
- const params = {
- id: 5,
- };
-
- try {
- const response = await axios({
- method: "delete",
- url: "/data.json",
- params: params,
- });
-
- console.log(response);
- } catch (error) {
- console.error("DELETE 请求错误:", error);
- }
- }
-
- // 在组件挂载后分别调用 sendDeleteRequestWithParams 和 sendDeleteRequestWithConfig 函数,确保请求被发送
- onMounted(() => {
- sendDeleteRequestWithParams();
- sendDeleteRequestWithConfig();
- });
- </script>
使用类似post请求方式,把axios.delete()中的params改为data,这样请求会把内容放入请求体里面
- <script setup>
- import axios from 'axios';
-
- // 使用别名法:DELETE 请求携带 data 参数(非标准用法)
- async function sendDeleteRequestWithDataAlias() {
- try {
- const response = await axios.delete("/data.json", {
- data: {
- id: 5,
- },
- });
-
- console.log(response, "DELETE with data (using alias)");
- } catch (error) {
- console.error("DELETE 请求错误(使用别名法):", error);
- }
- }
-
- // 不使用别名法:通过传递相关配置创建 DELETE 请求并携带 data 参数(非标准用法)
- async function sendDeleteRequestWithDataConfig() {
- const data = {
- id: 5,
- };
-
- try {
- const response = await axios({
- method: "delete",
- url: "/data.json",
- data: data,
- });
-
- console.log(response, "DELETE with data (using config)");
- } catch (error) {
- console.error("DELETE 请求错误(使用配置法):", error);
- }
- }
-
- // 在组件挂载后分别调用 sendDeleteRequestWithDataAlias 和 sendDeleteRequestWithDataConfig 函数,确保请求被发送
- onMounted(() => {
- sendDeleteRequestWithDataAlias();
- sendDeleteRequestWithDataConfig();
- });
- </script>
`并发请求`: 在同一时间发送多个不同的请求到后端服务,最后同一处理不同服务的响应结果
- <script setup>
- import axios from 'axios';
-
- // 定义一个异步函数,用于并发请求并处理响应结果
- async function handleConcurrentRequests() {
- try {
- // 同时发起两个 GET 请求
- const [dataRes, cityRes] = await Promise.all([
- axios.get("/data.json"),
- axios.get("/city.json"),
- ]);
-
- // 打印两个请求的响应结果
- console.log("Data Response:", dataRes);
- console.log("City Response:", cityRes);
- } catch (error) {
- // 处理可能出现的错误
- console.error("并发请求错误:", error);
- }
- }
-
- // 在组件挂载后调用 handleConcurrentRequests 函数,确保请求被发送
- onMounted(() => {
- handleConcurrentRequests();
- });
- </script>
注意:axios.all的参数是请求函数的数组,在对应的回调then中,调用axios.spead对返回值进行处理即可。
并发请求的应用场景:需要同时进行多个请求,并且需要同时处理接口调用的返回值的时候,我们可以使用并发请求。
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]])
- <script setup>
- import axios from 'axios';
-
- const commonConfig = {
- baseURL: 'https://api.example.com/v1',
- headers: {
- 'Content-Type': 'application/json',
- Authorization: 'Bearer your-access-token',
- },
- };
-
- // 示例:使用 axios.request(config)
- async function makeRequestUsingRequest() {
- const customConfig = {
- ...commonConfig,
- method: 'GET',
- url: '/users/123',
- };
-
- try {
- const response = await axios.request(customConfig);
- console.log('axios.request:', response.data);
- } catch (error) {
- console.error('axios.request Error:', error.message);
- }
- }
-
- // 示例:使用 axios.get(url[, config])
- async function makeGetRequestUsingGetMethod() {
- const getEndpoint = '/users/123';
- const getConfig = {
- ...commonConfig,
- };
-
- try {
- const response = await axios.get(getEndpoint, getConfig);
- console.log('axios.get:', response.data);
- } catch (error) {
- console.error('axios.get Error:', error.message);
- }
- }
-
-
- // 示例:使用 axios.head(url[, config])
- async function makeHeadRequest() {
- const headEndpoint = '/users/123';
- const headConfig = {
- ...commonConfig,
- };
-
- try {
- const response = await axios.head(headEndpoint, headConfig);
- console.log('axios.head:', response.headers); // 注意:HEAD 请求的响应没有 data 属性,仅关注 headers
- } catch (error) {
- console.error('axios.head Error:', error.message);
- }
- }
-
- // 在组件挂载后调用各示例函数,确保请求被发送
- onMounted(() => {
- makeRequestUsingRequest();
- makeHeadRequest();
- });
- </script>
- {
- //data是服务器提供的响应
- data:{},
-
- //服务器返回的http状态码
- status: 200,
-
- //statusText是服务器返回的http状态信息
- statusText: 'ok',
-
- //heades是服务器响应中携带的headers
- headers:{},
-
- //config是axios进行的设置,目的是为了请求(request)
- config:{},
- }
-
- //使用then后,response中将包含上述信息
- axios.get('/user/12345').then(response={
- console.log(response.data);
- console.log(response.status);
- console.log(response.statusText);
- console.log(response.headers);
- console.log(response.config);
- })
比如:后端接口地址有多个(www.test.com、www.example.com),并且超时时长不同,比如1000ms、2000ms,这个时候,我们可以创建实例,利用axios实例进行网络请求。
思路如下:创建多个实例,配置不同的超时时长,用不同的实例去请求不同的接口。使用axios.acreate来创建实例,配置相关信息,进行网络请求。代码如下:
- <script setup>
- import axios from 'axios';
-
- // 创建 Axios 实例 1
- const instance1 = axios.create({
- baseURL: "http://localhost:8080",
- timeout: 1000,
- });
-
- // 使用实例 1 发送 GET 请求
- async function makeRequestUsingInstance1() {
- try {
- const response = await instance1.get("/data.json");
- console.log("Instance 1 Response:", response.data);
- } catch (error) {
- console.error("Instance 1 Error:", error.message);
- }
- }
-
- // 创建 Axios 实例 2
- const instance2 = axios.create({
- baseURL: "http://localhost:8081",
- timeout: 2000,
- });
-
- // 使用实例 2 发送 GET 请求
- async function makeRequestUsingInstance2() {
- try {
- const response = await instance2.get("/city.json");
- console.log("Instance 2 Response:", response.data);
- } catch (error) {
- console.error("Instance 2 Error:", error.message);
- }
- }
-
- // 在组件挂载后调用各示例函数,确保请求被发送
- onMounted(() => {
- makeRequestUsingInstance1();
- makeRequestUsingInstance2();
- });
- </script>
备注:此时我们就可以访问http://loacalhost:8080与http://loacalhost:8081两个不同域名的接口,并且使用不同的配置。
(1)配置列表:
- baseURL:请求的域名 / 基本地址。
- timeout:请求的超时时长,默认:1000毫秒(ms),超过这个时长后端会报(返回)401超时。
- url:请求的路径。
- method:请求的方法。如:get、post、put、patch、delete等。
- headers:请求头。
- params:将请求参数拼接到url上
- data:将请求参数放置到请求体里
- let instance = axios.create({
- // 创建实例时设置配置默
- baseURL: "", //请求的域名/基本地址
- timeout: 2000, //请求的超时时长,单位毫秒,默认。
- url: "/data.json", //请求路径
- method: "get", //请求方法
- headers: {
- //设置请求头————我们可以给请求头添加一些参数
- token: "",
- post: {
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
- }
- },
- params: { id: 5 }, //将请求参数拼接到url上
- data: { id: 5 }, //将请求参数放置到请求体里
- });
(2)三种配置方式:
- axios.defaults.baseURL = 'http://localhost:8080'
- axios.defaults.timeout = 2000
备注:在一个项目当中,我们经常存在需要多次请求同一个基本URL下的不同路由,如果每次发送请求都书写一遍基本URL无疑会产生大量的代码重复,因此,可以使用全局配置来简化代码。 默认配置 | Axios 中文文档 | Axios 中文网
- let instance = axios.create();
- instance.defaults.timeout = 3000
- instance.get('/data.json',{
- timeout:5000
- })
配置方式的优先级:axios全局配置 < axios实例配置 < axios请求配置
(3)常用参数配置的使用方法
- let instance1 = axios.create({
- baseURL: "http://localhost:9090",
- timeout: 1000,
- });
- instance1
- .get("/contactList", {
- params: {
- id: 5,
- },
- })
- .then((res) => {
- console.log(res);
- });
分析:配置的参数为baseURL:‘http://localhost:8080’,timeout:1000,method:‘get’,params:{ id:10},url:’/contactList’
- let instance2 = axios.create({
- baseURL: "http://localhost:8081",
- timeout: 3000,
- });
- instance2
- .get("/contactList", {
- timeout: 5000,
- })
- .then((res) => {
- console.log(res);
- });
分析:配置的参数为baseURL:‘http://localhost:8081’,timeout:5000,method:‘get’,url:’/contactList’
注意:最终的有效配置是由优先级高的覆盖优先级低的。
何为拦截器?就是在请求前或响应被处理前拦截他们,分为两种:请求拦截器与响应拦截器
(1)axios拦截器的使用方法
- // 添加请求拦截器
- /*需要拦截请求的原因
- * 1.config中包含了某些不符合服务器要求的信息
- * 2.发送网络请求的时候需要向用户展示一些加载中的图标
- * 3.网站需要登录才能请求资源,也就是需要token才能请求资源*/
- axios.interceptors.request.use(config => {
- // 在发送请求之前做些什么
- console.log(config)
- return config; //拦截器里一定要记得将拦截的结果处理后返回,否则无法进行数据获取
- }, err=>{
- // 对请求错误做些什么
- console.log(err)
- return Promise.reject(err) // 在请求错误的时候的逻辑处理
- });
备注:可以为自定义 axios 实例添加拦截器
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。