详解ajax、fetch、axios的区别

众所周知它们都用来发送请求,其实它们区别还蛮大的。这也是面试中的高频题,本文将详细进行讲解。

1. ajax

英译过来是Aysnchronous JavaScript And XML,直译是异步JSXMLXML类似HTML,但是设计宗旨就为了传输数据,现已被JSON代替),解释一下就是说XML作为数据传输格式发送JS异步请求 。但实际上ajax是一个一类技术的统称的术语 ,包括XMLHttpRequestJSCSSDOM等,它主要实现网页拿到请求数据后不用刷新整个页面也能呈现最新的数据

下面我们简单封装一个ajax请求【面试高频题】:

javascript 复制代码
const ajaxGet = function (url) {
    const xhr = new XMLHttpRequest()
    xhr.open('get', url)
    xhr.onreadystatechange = () => {
        if (xhr.readyState == 4) {
            if (xhr.status >= 200 && xhr.status < 400) {
                console.log(xhr.response);  // 响应结果
            }
        }
    }
    xhr.onerror = (error) => {
        console.log(error, xhr.status)
    }
    xhr.send()
}

2. fetch

它其实就是一个JS自带的发送请求的一个api ,拿来跟ajax对比是完全不合理的,它们完全不是一个概念的东西,适合拿来和fetch对比的其实是xhr,也就是上面封装ajax请求的代码里的XMLHttpRequest,这两都是JS自带的发请求的方法,而fetchES6出现的,自然功能比xhr更强,主要原因就是它是基于Promise的,它返回一个Promise ,因此可以使用.then(res => )的方式链式处理请求结果,这不仅提高了代码的可读性,还避免了回调地狱 (xhr通过xhr.onreadystatechange= () => {}这样回调的方式监控请求状态,要是想在请求后再发送请求就要在回调函数内再发送请求,这样容易出现回调地狱)的问题。而且JS自带,语法也非常简洁,几行代码就能发起一个请求,用起来很方便,据说大佬都爱用。

它的特点是:

  • 使用 promise,不使用回调函数。
  • 采用模块化设计,比如 rep、res 等对象分散开来,比较友好。
  • 通过数据流对象处理数据,可以提高网站性能。

下面我们简单写个fetch请求的示例:

javascript 复制代码
// get请求
fetch('http://127.0.0.1:8000/get')
    .then(res => {
    if (!res.ok) {
        throw new Error('请求错误!状态码为:', res.status)
    }
    return res.text()
}).then(data => {
    console.log(data);
})
// post请求
fetch('http://127.0.0.1:8000/post', {
    method: 'post',
    headers: {
        'Content-Type': 'application/json'
    },
    mode: 'no-cors',  // 设置cors表示只能发送跨域的请求,no-cors表示跨不跨域都能发
    body: JSON.stringify({
        name: 'zhangsan',
        age: 18
    })
}).then(res => {
    return res.json()
}).then(data => {
    console.log(data);
})

3. axios

axios是用于网络请求的第三方库,它是一个库 。axios利用xhr进行了二次封装的请求库 ,xhr只是axios中的其中一个请求适配器,axios在nodejs端还有个http的请求适配器 ;axios = xhr + http;它返回一个Promise。【项目中经常需要封装的axios】

它的特点:

  • 在浏览器环境中创建 XMLHttpRequests;在node.js环境创建 http 请求
  • 返回Promise
  • 拦截请求和响应
  • 自动转换 JSON 数据
  • 转换请求数据和响应数据
  • 取消请求

它的基础语法是:

javascript 复制代码
// 发送 Get 请求
axios({
    method: 'get',
    url: '',
    params: {}  // 查询query使用params
})
// 发送 Post 请求
axios({
    method: 'post',
    url: '',
    data: {}  // 请求体body用data
})

下面我们在vue项目中封装一个使用axios实现的请求。

libs/config.js:配置文件

javascript 复制代码
const serverConfig = {
  baseUrl: "http://127.0.0.1:8000", // 请求基础地址,可根据环境自定义
  useTokenAuthentication: false, // 是否开启token认证
};
export default serverConfig;

libs/request.js:封装请求

javascript 复制代码
import axios from "axios";  // 第三方库 需要安装
import serverConfig from "./config";
// 创建axios实例
const apiClient = axios.create({
  baseURL: serverConfig.baseUrl, // 基础请求地址
  withCredentials: false, // 跨域请求是否需要携带cookie
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json",
  },
  timeout: 10000, // 请求超时时间
});

// 请求拦截
apiClient.interceptors.request.use(
  (config) => {
    // 请求发送前的处理逻辑 比如token认证,设置各种请求头啥的
    // 如果开启token认证
    if (serverConfig.useTokenAuthentication) {
      // 请求头携带token
      config.headers.Authorization = localStorage.getItem("token");
    }
    return config;
  },
  (error) => {
    // 请求发送失败的处理逻辑
    return Promise.reject(error);
  }
);

// 响应拦截
apiClient.interceptors.response.use(
  (response) => {
    // 响应数据处理逻辑,比如判断token是否过期等等
    // 代码块
    return response;
  },
  (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 apiClient;

/api/index.js:配置请求接口,这里一个get一个post

javascript 复制代码
import apiClient from "@/libs/request";

let getInfo = (params) => {
  return apiClient({
    url: "/get",
    method: "get",
    params,  // axios的get请求query用params
  });
};
let postInfo = (params) => {
  return apiClient({
    url: "/post",
    method: "post",
    data: params,  // axios的post请求body用data
  });
};
export default {
  getInfo,
  postInfo,
};

App.vue:用于测试请求结果

javascript 复制代码
<script>
import api from './api/index.js'
export default {
    data() {
        return {
            isH5: true
        }
    },
    created() {
        this.init()
    },
    methods: {
        init() {
            api.getInfo().then(res => {
                console.log(res.data);
            })
            api.postInfo({
                name: 'zhangsan',
                age: '18'
            }).then(res => {
                console.log(res.data);
            })
        }
    },
}
</script>

结果如下:

4. 总结

总结一部分区别如下:【这三个东西差别真的很大】

Ajax fetch axios
类型 术语,技术的统称 js内置的api 第三方库
是否使用xhr二次封装
是否返回Promise
相关推荐
Qrun42 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp43 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.2 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl4 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front8 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰8 小时前
纯flex布局来写瀑布流
前端·javascript·css