Axios使用封装和跨域

作者: adm 分类: 前端 发布时间: 2022-11-25

1.安装

npm install axios --save
# 或者
yarn add axios

2.请求方式
Get、Delete请求:
这类请求也称作query请求。第一种方式为拼接url的形式传参:

axios.get('/user?username=korbin&password=12345')
.then(function (res) {
    console.log(res);
}).catch(function (err) {
    console.log(err);
});

6
第二种方式是封装到params中 (推荐) :

axios.delete('/user', {  //params参数必写 , 如果没有参数传{}也可以
    params: {  
       username: 'korbin',
       password: '123456'
    }
})
.then(function (res) {
    console.log(res);
})
.catch(function (err) {
    console.log(err);
});

Post、Put、Patch请求
若通过JSON(Content-Type: application/json )传参,则很简单,直接传参即可:

axios.post('/api/xxxx',
   {
      username:this.username,
      password:this.password
   }
)

若通过表单(application/x-www-form-urlencoded)传参,则需要将参数转化为URL的编码形式,有两种方式传参,第一种通过FormData对象:

var formData=new FormData();
formData.append('username','korbin');
formData.append('password','123456');
 
axios.post("/login",formData)
     .then((res) => {return res})
     .catch((err) => {return err})

第二种通过Qs模块:

npm install qs --save
# 或者
yarn add qs
axios.put('/api/xxxx',
   qs.stringify({
      username:this.username,
      password:this.password
   }),
)

3.配置和拦截器封装
axios除了使用上述的默认请求方法,还可以配置各种请求参数,和使用请求、响应拦截,使用方法和封装如下:


import axios from 'axios'
import {TOKEN_KEY} from "../constants/constant";

const config = {
    // 请求超时时间
    timeout: 10000,
    // 通过配置文件
    baseURL: 'http://localhost:8081'
    // 允许请求携带cookie信息
    // withCredentials: true
}

// axios 配置
const httpJson = axios.create({
    ...config,
    headers: {
        post: {'Content-Type': 'application/json;charset=utf-8'}
    }
})


// 请求拦截器
httpJson.interceptors.request.use(
    (request) => {
        // localStorage.setItem('token', 'eyJhbGdvcml0aG0iOiJIU0EyNTYiLCJ0eXBlIjoiSldUIn0=.eyJpc3N1ZXIiOiJ3aGVyZWFib3V0cy5pY3UiLCJvd25lciI6IjIwMTcwNTEwMjUiLCJwdXJwb3NlIjoiQXV0aGVudGljYXRpb24iLCJyZWNpcGllbnQiOiJCcm93c2VyIiwidGltZSI6MTYxNTcxNjI5NywiZXhwaXJlIjoxNjE1NzE4MDk3LCJkdXJhdGlvbiI6MTgwMDAwMDAwMDAwMCwiZXh0ZXJuYWwiOm51bGx9.bF-Yot7JZxWL_li2ZoIAlPOSiiBBZBP7it7JmDtQD94=')
        const token = localStorage.getItem(TOKEN_KEY)
        // 判断是否存在token,有则携带请求
        if (token) {
            request.headers.Token = token
        }
        return request
    },
    (error) => {
        return Promise.reject(error)
    }
)

// 响应拦截器
httpJson.interceptors.response.use(
    (response) => {
        // 响应了Token则更新Token
        const token = response.headers.token
        if (token) {
            localStorage.setItem(TOKEN_KEY, token)
        }
        return response
    },
    (error) => {
        if (error.response) {
            const {status} = error.response
            switch (status) {
                // 登录过期
                case 401: {
                    localStorage.removeItem('token')
                    return Promise.reject(error)
                }
                // 无权限
                case 403: {
                    return Promise.reject(error.response.data.message)
                }
                default: {
                }
            }
        }
        return Promise.reject(error)
    }
)

export default httpJson

进一步封装请求:

import httpJson from "./index";

/**
 * 封装 Get 方法
 * @param url  请求url
 * @param params  请求参数
 * @returns {Promise}
 */
const Get = (url, params = {}) => {
    return new Promise((resolve, reject) => {
        httpJson.get(url, {
            params: params,
        }).then((res) => {
            resolve(res.data);
        }).catch((err) => {
            reject(err);
        })
    });
}

/**
 * 封装 Post 请求
 * @param url
 * @param data
 * @returns {Promise}
 */

const Post = (url, data) => {
    return new Promise((resolve, reject) => {
        httpJson.post(url, data)
            .then((response) => {
                // 可以在这关闭进度条等...
                resolve(response.data);
            })
            .catch((err) => {
                reject(err);
            });
    });
}

/**
 * 封装 Delete 请求
 * @param url
 * @param params
 * @returns {Promise}
 */
const Delete = (url, params = {}) => {
    return new Promise((resolve, reject) => {
        httpJson.delete(url, {
            params: params,
        }).then((res) => {
            resolve(res.data);
        }).catch((err) => {
            reject(err);
        })
    });
}

/**
 * 封装 Put 请求
 * @param url
 * @param data
 * @returns {Promise}
 */

const Put = (url, data = {}) => {
    return new Promise((resolve, reject) => {
        httpJson.put(url, data)
            .then((response) => {
                resolve(response.data);
            })
            .catch((err) => {
                reject(err);
            });
    });
}

const axios = {
    get: Get,
    post: Post,
    delete: Delete,
    put: Put
}

export default axios

使用示例:

import axios from "../axios/api";

axios.put('http://localhost:8081/v1/test/put', {
            name: 'korbin',
            age: 12
        }).then((res)=> {
           console.log(res);
       }).catch((err)=> {
           console.log(err);
       })

解决跨域
在React中,配置请求代理,通过虚拟服务器代理发送请求来解决跨域问题,服务器间是不存在跨域问题的,跨域拦截只存在于浏览器。

安装 http-proxy-middleware:

$ npm install http-proxy-middleware --save
$ # 或
$ yarn add http-proxy-middleware

创建 src/setupProxy.js 并将以下内容放入该文件中:


const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
    app.use(
        '/api',
        createProxyMiddleware({
            target: 'https://www.baidu.com',
            pathRewrite: {
                "^/api": "/"
            },
            changeOrigin: true,
        })
    );
};

这样,例如/api/test,在代理和请求转发后的实际请求路径为https://www.baidu.com/test。包含/api的请求路径会被代理到https://www.baidu.com,且/api会被Rewrite为“。
————————————————

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!