通过 create 方法我们得到了一个 axios 的实例,该实例上有很多方法,比如拦截器等等。我们创建实例的时候可以配置一些基础设置,比如基础请求地址,请求超时等等。
- // 创建 axios 请求实例
- const serviceAxios = axios.create({
- baseURL: "", // 基础请求地址
- timeout: 10000, // 请求超时设置
- withCredentials: false, // 跨域请求是否需要携带 cookie
- });
我们在发送请求的时候可能需要携带一些信息在请求头上,比如 token 等,所以说我们就需要将请求拦截下来,处理一些我们的业务逻辑。
- // 创建请求拦截
- serviceAxios.interceptors.request.use(
- (config) => {
- // 如果开启 token 认证
- if (serverConfig.useTokenAuthorization) {
- config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
- }
- // 设置请求头
- if(!config.headers["content-type"]) { // 如果没有设置请求头
- if(config.method === 'post') {
- config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
- config.data = qs.stringify(config.data); // 序列化,比如表单数据
- } else {
- config.headers["content-type"] = "application/json"; // 默认类型
- }
- }
- console.log("请求配置", config);
- return config;
- },
- (error) => {
- Promise.reject(error);
- }
- );
axios 请求的返回结果里面包含了很多东西,我们的业务层面通常只需要后端返回的数据即可,所以我们需要设置相应拦截,在响应结果返回给业务层之前做一些操作。
- // 创建响应拦截
- serviceAxios.interceptors.response.use(
- (res) => {
- let data = res.data;
- // 处理自己的业务逻辑,比如判断 token 是否过期等等
- // 代码块
- return data;
- },
- (error) => {
- let message = "";
- if (error && error.response) {
- switch (error.response.status) {
- case 302:
- message = "接口重定向了!";
- break;
- case 400:
- message = "参数不正确!";
- break;
- case 401:
- message = "您未登录,或者登录已经超时,请先登录!";
- break;
- case 403:
- message = "您没有权限操作!";
- break;
- case 404:
- message = `请求地址出错: ${error.response.config.url}`;
- break;
- case 408:
- message = "请求超时!";
- break;
- case 409:
- message = "系统已存在相同数据!";
- break;
- case 500:
- message = "服务器内部错误!";
- break;
- case 501:
- message = "服务未实现!";
- break;
- case 502:
- message = "网关错误!";
- break;
- case 503:
- message = "服务不可用!";
- break;
- case 504:
- message = "服务暂时无法访问,请稍后再试!";
- break;
- case 505:
- message = "HTTP 版本不受支持!";
- break;
- default:
- message = "异常问题,请联系管理员!";
- break;
- }
- }
- return Promise.reject(message);
- }
- );
在 src 下面新建 http 文件夹,用来存储关于 axios 请求的一些文件,然后在 http 文件夹下新建 index.js 文件,用于封装我们的 axios,然后在新建 config 文件夹,主要用来创建配置文件,最后新建一个 api 文件夹,用于集中管理我们的接口。
- import axios from "axios";
- import serverConfig from "./config";
- import qs from "qs";
-
-
- // 创建 axios 请求实例
- const serviceAxios = axios.create({
- baseURL: serverConfig.baseURL, // 基础请求地址
- timeout: 10000, // 请求超时设置
- withCredentials: false, // 跨域请求是否需要携带 cookie
- });
-
-
- // 创建请求拦截
- serviceAxios.interceptors.request.use(
- (config) => {
- // 如果开启 token 认证
- if (serverConfig.useTokenAuthorization) {
- config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
- }
- // 设置请求头
- if(!config.headers["content-type"]) { // 如果没有设置请求头
- if(config.method === 'post') {
- config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
- config.data = qs.stringify(config.data); // 序列化,比如表单数据
- } else {
- config.headers["content-type"] = "application/json"; // 默认类型
- }
- }
- console.log("请求配置", config);
- return config;
- },
- (error) => {
- Promise.reject(error);
- }
- );
-
-
- // 创建响应拦截
- serviceAxios.interceptors.response.use(
- (res) => {
- let data = res.data;
- // 处理自己的业务逻辑,比如判断 token 是否过期等等
- // 代码块
- return data;
- },
- (error) => {
- let message = "";
- if (error && error.response) {
- switch (error.response.status) {
- case 302:
- message = "接口重定向了!";
- break;
- case 400:
- message = "参数不正确!";
- break;
- case 401:
- message = "您未登录,或者登录已经超时,请先登录!";
- break;
- case 403:
- message = "您没有权限操作!";
- break;
- case 404:
- message = `请求地址出错: ${error.response.config.url}`;
- break;
- case 408:
- message = "请求超时!";
- break;
- case 409:
- message = "系统已存在相同数据!";
- break;
- case 500:
- message = "服务器内部错误!";
- break;
- case 501:
- message = "服务未实现!";
- break;
- case 502:
- message = "网关错误!";
- break;
- case 503:
- message = "服务不可用!";
- break;
- case 504:
- message = "服务暂时无法访问,请稍后再试!";
- break;
- case 505:
- message = "HTTP 版本不受支持!";
- break;
- default:
- message = "异常问题,请联系管理员!";
- break;
- }
- }
- return Promise.reject(message);
- }
- );
- export default serviceAxios;
- const serverConfig = {
- baseURL: "https://smallpig.site", // 请求基础地址,可根据环境自定义
- useTokenAuthorization: true, // 是否开启 token 认证
- };
- export default serverConfig;
- import serviceAxios from "../index";
-
-
- export const getUserInfo = (params) => {
- return serviceAxios({
- url: "/api/website/queryMenuWebsite",
- method: "post",
- params,
- });
- };
- export const login = (data) => {
- return serviceAxios({
- url: "/api/user/login",
- method: "post",
- data,
- });
- };
注意:get 请求需要传 params,post 请求需要传 data。
- import { login } from "@/http/api/user"
- async loginAsync() {
- let params = {
- email: "123",
- password: "12321"
- }
- let data = await login(params);
- console.log(data);
- }
- const serviceAxios = axios.create({
- baseURL: "", // 基础请求地址
- // 如 baseURL: baseUrl.apiBaseUrl, url = base url + request url
- timeout: 10000, // 请求超时设置
- withCredentials: false, // 跨域请求是否需要携带 cookie
- });
-
-
- // 添加请求拦截器
- service.interceptors.request.use(
- function (config) {
- // 判断是否存在token,如果存在的话,则每个http header都加上token
- let appToken = store.state.app.appToken
- if (appToken) {
- config.headers['AppToken'] = appToken
- } else {
- config.headers['AppToken'] = window.localStorage.getItem('AppToken')
- }
- return config
- },
- function (error) {
- // 对请求错误做些什么
- return Promise.reject(error)
- }
- )
- // 添加响应拦截器
- service.interceptors.response.use(
- function (response) {
- let contentType = response.headers['content-type']
- if (typeof contentType != 'undefined' && contentType.includes('application/octet-stream')) {
- return response.data
- }
- let { code, message, content } = response.data
- switch (code) {
- case 500000:
- Toast({ message: message, forbidClick: true })
- return Promise.reject(content)
- //登录已过期
- case 100003:
- Toast({ message: message, forbidClick: true })
- toLogin()
- return Promise.reject(content)
- //未登录
- case 100004:
- Toast({ message: message, forbidClick: true })
- toLogin()
- return Promise.reject(content)
- //未绑定银行卡
- case 100005:
- Toast({ message: message, forbidClick: true })
- router.replace({ path: '/notice' })
- return Promise.reject(content)
- //未实名认证
- case 100006:
- Toast({ message: message, forbidClick: true })
- router.replace({ path: '/notice' })
- return Promise.reject(content)
- default:
- return Promise.resolve(content)
- }
- },
- function (error) {
- return Promise.reject(error)
- }
- )