axios快速入门

一、环境配置

1.1概述

上古浏览器页面在向服务器请求数据时,因为返回的是整个页面的数据,页面都会强制刷新一下,这对于用户来讲并不是很友好。并且我们只是需要修改页面的部分数据,但是从服务器端发送的却是整个页面的数据,十分消耗网络资源。而我们只是需要修改页面的部分数据,也希望不刷新页面,因此异步网络请求就应运而生。

Ajax(Asynchronous JavaScript and XML):异步网络请求。Ajax能够让页面无刷新的请求数据。

实现ajax的方式有多种,如jQuery封装的ajax,原生的XMLHttpRequest,以及axios。但各种方式都有利弊

原生的XMLHttpRequest的配置和调用方式都很繁琐,实现异步请求十分麻烦

jQuery的ajax相对于原生的ajax是非常好用的,但是没有必要因为要用ajax异步网络请求而引用jQuery框架

1.2安装

bash 复制代码
pnpm i axios --save-dev

在项目中创建untils/request.js文件

javascript 复制代码
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

1.3示例

bash 复制代码
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: {
      //
      //   }
      // }
    })
},
bash 复制代码
@CrossOrigin

1.4相关文档

请求配置 | Axios中文文档 | Axios中文网

二、跨域资源访问

2.1会话存储

随着富客户端快速发展,普通本地存储(cookie)无法满足前端需要的大量数据的存储需求 HTML5,引入Web存储,Web应用程序可以在用户的浏览器中本地存储数据

  • 包括本地数据库技术 IndexedDB/WebSQL等
  • 包括基于键值对 LocalStorage/SessionStorage

Web Storage提供了两种在客户端存储数据的方式,即**LocalStorage和SessionStorage**,它们都用于以键值对的形式保存数据。具体如下:

  • LocalStorage,本地全局数据存储。永久性数据,需手动删除,无加密,可跨域调用
  • SessionStorage,当前页面标签存储。仅与当前页面绑定,标签/浏览器关闭,数据自动销毁

2.2CORS policy

发出请求的地址与目标地址,域名(IP)+端口一致,即为,同源 浏览器持有用户大量敏感数据。因此,同源安全策略,即限制跨域请求(尤其基于Ajax发出的请求),是浏览器的一种安全机制

方法1,后端允许跨域请求

方法1,前端同时需要修改axios全局请求的基本地址。无需vue配置 方法1,不利于开发环境与生产环境间的切换

方法2,后端无需改动。前端, vue.config.js添加配置

此方法仅在开发测试环境下有效

三、 Axios基本入门

3.1概述

axios可以请求的方法:

  • get:获取数据,请求指定的信息,返回实体对象
  • post:向指定资源提交数据(例如表单提交或文件上传)
  • put:更新数据,从客户端向服务器传送的数据取代指定的文档的内容
  • patch:更新数据,是对put方法的补充,用来对已知资源进行局部更新
  • delete:请求服务器删除指定的数据

3.2get方法

方式一:请求别名的使用

axios.get(url[, config]) 用于获取数据

  • 如果不带有参数,代码如下:
javascript 复制代码
<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>
  • 如果带有参数,代码如下:
javascript 复制代码
<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传递相关配置来创建请求

  • 如果不带参数,代码如下:
javascript 复制代码
<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>

如果带有参数,代码如下

javascript 复制代码
<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 的形式进行传递,即?后的字符串则为其请求参数,并以&做为分隔符。

3.3post方法

post请求常用的数据请求格式有三种:

  1. Content-Type : application/x-www-form-urlencoded。ajax默认的数据格式。请求体中的数据会以json字符串的形式发送到后端。
  2. Content-Type : application/json ; charset=utf-8。axios默认的数据格式。请求体中的数据会以普通表单形式(键值对)发送到后端。
  3. Content-Type : multipart/form-data 。它会将请求体的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。

Content-Type:application/x-www-form-urlencoded

javascript 复制代码
<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>

Content-Type: multipart/form-data(常用于表单提交(图片上传、文件上传))

bash 复制代码
<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}

Content-Type: application/json(常用)

  • 方式一:请求别名的使用

axios.post(url[, data[, config]]) 用于发送数据 `data`对象是作为请求主体被发送的数据

axios发送post无参请求,代码如下:

javascript 复制代码
<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种传参形式,代码如下:

① 查询字符串形式

javascript 复制代码
<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>

② 对象形式

javascript 复制代码
<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>
  • 方式二:通过向axios传递相关配置来创建请求
javascript 复制代码
<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>

3.4put和patch方法

put和patch请求与post请求用法一样类似,同样有x-www-form-urlencoded、applicition/json和form-data,只有method不同,其他相同。在此不过多赘述了,简单写一下!

javascript 复制代码
<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>

3.5delete方法

axios.delete(url[, config])与axios.get(url[, config])用法基本相似,但是作用不同,它用于删除数据,同get方法一样也可以有几种写法 。

delete请求有时候需要把参数拼接到URL上 ,有时候像post请求那样把参数放在请求体里面。至于具体怎么调用,需要和后端商量好!

  • 方式一:get - params
javascript 复制代码
<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 - data

使用类似post请求方式,把axios.delete()中的params改为data,这样请求会把内容放入请求体里面

javascript 复制代码
<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>

3.6并发请求

`并发请求`: 在同一时间发送多个不同的请求到后端服务,最后同一处理不同服务的响应结果

javascript 复制代码
<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对返回值进行处理即可。

并发请求的应用场景:需要同时进行多个请求,并且需要同时处理接口调用的返回值的时候,我们可以使用并发请求。

3.7Restful风格的API

  • 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]])
javascript 复制代码
<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>

3.8响应信息

javascript 复制代码
{
    //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);
})

四、Axios进阶用法

4.1axios实例的创建与配置

axios实例的创建

比如:后端接口地址有多个(www.test.comwww.example.com),并且超时时长不同,比如1000ms、2000ms,这个时候,我们可以创建实例,利用axios实例进行网络请求。

思路如下:创建多个实例,配置不同的超时时长,用不同的实例去请求不同的接口。使用axios.acreate来创建实例,配置相关信息,进行网络请求。代码如下:

javascript 复制代码
<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两个不同域名的接口,并且使用不同的配置。

axios实例的相关配置

(1)配置列表:

  • baseURL:请求的域名 / 基本地址。

  • timeout:请求的超时时长,默认:1000毫秒(ms),超过这个时长后端会报(返回)401超时。

  • url:请求的路径。

  • method:请求的方法。如:get、post、put、patch、delete等。

  • headers:请求头。

  • params:将请求参数拼接到url上

  • data:将请求参数放置到请求体里

javascript 复制代码
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全局配置
javascript 复制代码
axios.defaults.baseURL = 'http://localhost:8080'
axios.defaults.timeout = 2000

备注:在一个项目当中,我们经常存在需要多次请求同一个基本URL下的不同路由,如果每次发送请求都书写一遍基本URL无疑会产生大量的代码重复,因此,可以使用全局配置来简化代码。 默认配置 | Axios 中文文档 | Axios 中文网

  • axios实例配置
javascript 复制代码
let instance = axios.create();
instance.defaults.timeout = 3000
  • axios请求配置
javascript 复制代码
instance.get('/data.json',{
    timeout:5000
})

配置方式的优先级:axios全局配置 < axios实例配置 < axios请求配置

(3)常用参数配置的使用方法

  • 示例1:
javascript 复制代码
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'

  • 示例2:
javascript 复制代码
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'

**注意:**最终的有效配置是由优先级高的覆盖优先级低的。

4.2拦截器

何为拦截器?就是在请求前或响应被处理前拦截他们,分为两种: ++请求拦截器++ ++响应拦截器++

(1)axios拦截器的使用方法

  • 请求拦截器 ------在请求之前拦截请求
javascript 复制代码
    // 添加请求拦截器
   /*需要拦截请求的原因
    *   1.config中包含了某些不符合服务器要求的信息
    *   2.发送网络请求的时候需要向用户展示一些加载中的图标
    *   3.网站需要登录才能请求资源,也就是需要token才能请求资源*/
    axios.interceptors.request.use(config => {
      // 在发送请求之前做些什么
      console.log(config)
      return config; //拦截器里一定要记得将拦截的结果处理后返回,否则无法进行数据获取
    }, err=>{
        // 对请求错误做些什么 
        console.log(err)
        return Promise.reject(err) // 在请求错误的时候的逻辑处理
    });

备注:可以为自定义 axios 实例添加拦截器 👇

javascript 复制代码
  var instance = axios.create([config]);
  instance.interceptors.request.use(function () {/*...*/});
​
  • 响应拦截器 ------在被then,catch处理前拦截响应
javascript 复制代码
    // 添加响应拦截器
    axios.interceptors.response.use(res => {
      // 在请求成功后的数据处理 
      console.log(res)
      return res.data; // 对响应数据做点什么
    }, err=>{
        // 对响应错误做些什么
        console.log(err)
        return Promise.reject(err)  // 在响应错误的时候的逻辑处理
    });
  • 取消拦截器(了解)
javascript 复制代码
	let inter = axios.interceptors.request.use(config=>{
        config.header={
            auth:true
        }
        return config
    })
    axios.interceptors.request.eject(inter)

4.3封装

javascript 复制代码
export function request(config) {
    // 1. 创建axios实例
    const instance = axios.create({
      baseURL: "http://localhost:8080",
      timeout: 5000,
    });
    // ​2. axios拦截器的使用
    // 2.1 添加请求拦截器
    /** 需要拦截请求的原因
     *   1.config中包含了某些不符合服务器要求的信息
     *   2.发送网络请求的时候需要向用户展示一些加载中的图标
     *   3.网站需要登录才能请求资源,也就是需要token才能请求资源
     */
    instance.interceptors.request.use(
      (config) => {
        // 在发送请求之前做些什么
        return config; //拦截器里一定要记得将拦截的结果处理后返回,否则无法进行数据获取
      },
      (err) => {
        // 对请求错误做些什么
        return Promise.reject(err); // 在请求错误的时候的逻辑处理
      }
    );
    // 2.2 添加响应拦截器
    instance.interceptors.response.use(
      (res) => {
        // 在请求成功后对响应数据做处理
        return res; // 对响应数据做点什么
      },
      (err) => {
        // 对响应错误做些什么
        return Promise.reject(err); // 在响应错误的时候的逻辑处理
      }
    );
    // 3. 发送网络请求
    //axios实例本身返回的就是Promise对象,直接调用即可
    return instance(config);
}

4.4全局异常信息警告框

4.5错误处理

结合请求拦截器与响应拦截器来说,不管是请求错误还是响应错误,都会执行catch方法。

(1)请求错误的常见状态码以4开头,如401-请求超时、404-接口未找到;

(2)响应错误的常见状态码以5开头,如500-服务器错误、502-服务器重启等。

javascript 复制代码
	// 请求拦截器
    axios.interceptors.request.use(
      config => {
        // 在发送请求前做些什么
        return config;
      },
      err => {
        // 在请求错误的时候的逻辑处理
        return Promise.reject(err);
      }
    );
 
    // 响应拦截器
    axios.interceptors.response.use(
      res => {
        // 在请求成功后的数据处理
        return res;
      },
      err => {
        // 在响应错误的时候的逻辑处理
        return Promise.reject(err);
      }
    ); 
 
	axios
      .get("/data.json")
      .then(res => {
        console.log(res);
      })
      .catch(err => {
        console.log(res);
      });

五、封装

request.js

在项目src目录下新建utils文件夹,然后在其中新建 request.js文件,这个文件是主要书写axios的封装过程。

javascript 复制代码
/****   request.js   ****/
// 导入axios
import axios from "axios";
// 使用element-ui Message做消息提醒
import { Message } from "element-ui";
// 1. 创建新的axios实例,
const service = axios.create({
  // 公共接口--webpack中的全局变量process.env.BASE_API
  // 为了适应多个后台或者开发的时候的api地址和发布的时候的api地址不一样这种情况
  baseURL: process.env.BASE_API,
  // 超时时间 单位是ms,这里设置了3s的超时时间
  timeout: 3 * 1000,
});
// 2. 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加
 
    config.data = JSON.stringify(config.data); // 数据转化,也可以使用qs转换
    config.headers = {
      "Content-Type": "application/x-www-form-urlencoded", // 配置请求头
    };
    //注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
    const token = getCookie("名称"); // 这里取token之前,你肯定需要先拿到token,存一下
    if (token) {
      config.params = { token: token }; // 如果要求携带在参数中
      config.headers.token = token; // 如果要求携带在请求头中
    }
 
    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);
 
// 3. 响应拦截器
service.interceptors.response.use(
  (response) => {
    //接收到响应数据并成功后的一些共有的处理,关闭loading等
 
    return response;
  },
  (error) => {
    /* ****  接收到异常响应的处理开始  **** */
    if (error && error.response) {
      // 1. 公共错误处理
      // 2. 根据响应码具体处理
      switch (error.response.status) {
        case 400:
          error.message = "错误请求";
          break;
        case 401:
          error.message = "未授权,请重新登录";
          break;
        case 403:
          error.message = "拒绝访问";
          break;
        case 404:
          error.message = "请求错误,未找到该资源";
          window.location.href = "/NotFound";
          break;
        case 405:
          error.message = "请求方法未允许";
          break;
        case 408:
          error.message = "请求超时";
          break;
        case 500:
          error.message = "服务器端出错";
          break;
        case 501:
          error.message = "网络未实现";
          break;
        case 502:
          error.message = "网络错误";
          break;
        case 503:
          error.message = "服务不可用";
          break;
        case 504:
          error.message = "网络超时";
          break;
        case 505:
          error.message = "http版本不支持该请求";
          break;
        default:
          error.message = `连接错误${error.response.status}`;
      }
    } else {
      // 超时处理
      if (JSON.stringify(error).includes("timeout")) {
        Message.error("服务器响应超时,请刷新当前页");
      }
      error.message("连接服务器失败");
    }
 
    Message.error(error.message);
 
    /* ****  处理结束  **** */
    // 如果不需要错误处理,以上的处理过程都可省略
    return Promise.resolve(error.response);
  }
);
 
// 4. 导入文件
export default service;

Axios中的http.js

在项目src目录下的utils文件夹中新建 http.js文件,这个文件是主要书写几种请求方式的封装过程。

javascript 复制代码
// api.js有两种导出方式,分类导出和全部导出
 
// 分类导出
import http from '../utils/http'
/**
 *  @params resquest 请求地址 例如:http://197.82.15.15:8088/request/...
 *  @param '/testIp'代表vue-cil中config,index.js中配置的代理
 */
let resquest = "/testIp/request/"
 
// get请求
export function getListAPI(params){
    return http.get(`${resquest}/getList.json`,params)
}
// post请求
export function postFormAPI(params){
    return http.post(`${resquest}/postForm.json`,params)
}
// put 请求
export function putSomeAPI(params){
    return http.put(`${resquest}/putForm.json`,params)
}
// delete 请求
export function deleteListAPI(params){
    return http.delete(`${resquest}/deleteList.json`,params)
}
 
// 全部导出
import http from '../utils/http'
/**
 *  @params resquest 请求地址 例如:http://197.82.15.15:8088/request/...
 *  @param '/testIp'代表vue-cil中config,index.js中配置的代理
 */
let resquest = "/testIp/request/"
 
// get请求
export default{
 	getListAPI(params){
    	return http.get(`${resquest}/getList.json`,params)
	},
	postFormAPI(params){
    	return http.post(`${resquest}/postForm.json`,params)
	},
    putFormAPI(params){
    return http.put(`${resquest}/putForm.json`,params)
    },
    deleteListAPI(params){
    return http.delete(`${resquest}/deleteList.json`,params)
    }
}

调用

javascript 复制代码
// 把api分类导入,用到哪个api 就调用哪个接口 ------------适用于上面接口的分类导出
import {getListAPI,postFormAPI, putSomeAPI, deleteListAPI} from '@/api/api'
 
  methods: {
      // promise调用,链式调用, getList()括号内只接受参数;
      // get不传参
      getList() {
        getListAPI().then(res => console.log(res)).catch(err => console.log(err))
      },
	  // post传参
      postForm(formData) {
        let data = formData
        postFormAPI(data).then(res => console.log(res)).catch(err => console.log(err))
      },
 
      // async await同步调用
      async postForm(formData) {
        const postRes = await postFormAPI(formData)
        const putRes = await putSomeAPI({data: 'putTest'})
        const deleteRes = await deleteListAPI(formData.name)
        // 数据处理
        console.log(postRes);
        console.log(putRes);
        console.log(deleteRes);
      },
   }
 
 
// 把api全部导入,然后用到哪个api调用哪个api ------------适用于全部导出
 import api from '@/api/api'
   methods: {
     getList() {
        api.getListAPI(data).then(res => {
        // 数据处理
        }).catch(err => console.log(err))
      }
    } 
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试