ajax与axios与fetch的比较

1.jq的ajax是对原生的xhr进行的封装,封装的基本上很全面,没啥大的毛病;

但是一般来说,做jq项目,还是很有必要用promise进行二次封装成自己需要的;

比如超时的设置,token的设置,返回头信息类型的设置,对于接口报错的统一处理,特定code的处理等等;

下图贴上我get请求的一般写法:

function ajaxGet(url, data) {
    return new Promise(function(resolve, reject) {
        $.ajax({
            type: "get",
            timeout: 120000, //超时时间设置,单位毫秒
            url: url,
            data: data,
            headers: {
                token: window.localStorage.getItem("token"),
            },
            success: function(res) {
                if (res.code == 200) {
                    resolve(res);
                } else if (res.code == 403) {
                    window.localStorage.removeItem('token');
                    $.message({
                        // message: '登录过期,请重新登录',
                        message: res.msg,
                        type: 'error',
                    });
                    setTimeout(() => {
                        window.location.href = "login.html";
                    }, 1000);
                } else {
                    reject(res.msg);
                    $.message({
                        message: res.msg,
                        type: 'error',
                    });
                }
            },
            error: function(err) {
                reject('服务器端响应超时,请稍后再试');
                $.message({
                    message: '服务器端响应超时,请稍后再试',
                    type: 'error',
                });
            },
        });
    });
}

同时也保留了,每个接口的处理的能力

缺点吧,回调地狱问题,不过引入bable,使用await, async也可以解决

其他基本没啥大问题

2.axios,也是对原生XHR的封装

axios使用上跟promise基本一样,他的all,race与promise一样,很方便;

使用then解决回调地狱的问题,当然用await, async更佳

同理axios能帮助到我们的东西基本上面一样多,特别是他请求拦截,响应拦截这一块,有帮我们封装

axios.defaults.timeout = 60000; //超时响应
// 请求拦截
axios.interceptors.request.use(config => {
        // 1. 这个位置就请求前最后的配置
        // 2. 当然你也可以在这个位置 加入你的后端需要的用户授权信息
        let token = localStorage.getItem('token');
        if (token) {
            config.headers.token = token;
        }
        return config;
    }, error => {
        return Promise.reject(error);
    })
    // 响应拦截
axios.interceptors.response.use(response => {
    // 请求成功
    // 1. 根据自己项目需求定制自己的拦截
    // 2. 然后返回数据
    if (response.data.code == 200) {
        return response.data;
    } else if (response.data.code == 403) {
        vue.$message.error("token失效,请去登录");
        // 重定向到登录页
        router.push('/').catch(err => {
            console.log('all good')
        })
    } else {
        vue.$message.error(response.data.msg);
    }
}, error => {
    // 请求失败
    if (error && error.response) {
        switch (error.response.status) {
            case 400:
                // 对400错误您的处理
                break
            case 401:
                // 对 401 错误进行处理
                break
            default:
                // 如果以上都不是的处理
                return Promise.reject(error);
        }
    }

})

3.fetch,就是底层浏览器的api,使用的时候,也需要我们进行封装

封装的内容,都大致一样;

优点基本也axios一样吧;

但是他不支持超时控制,需要自己用promise的race去控制;

当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 400 或 500。

相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ), 仅当网络故障时或请求被阻止时,才会标记为 reject。

所以一般通过返回的ok值去判断

无封装版本:

let content = {
    pageNum: 1,
    pageSize: 10,
};
fetch('/xxxx',{
     headers: {
        token: window.localStorage.getItem("token"),
        "Content-Type": "application/json",
    },
     method: 'post',
     body: JSON.stringify(content),
})
.then(response => {
    // 判断接口返回的地方if (response.ok) {
      return response.json()
    } else {
      return Promise.reject('something went wrong!')
    }
})
.then(data => {console.log('data is1', data)
    return data
})
.then(data => console.log('data is2', data))
.catch(error => console.log('error is', error));