ajax和axios、fetch的区别


axios、fetch 和 ajax的区别 在网络上存在很多文章。现针对自己的情况,来重新整理一份,便于自己记忆和理解。内容参考了网络上的众多文章。

XMLHttpRequest

浏览器通过XMLHttpRequest 对象进行 HTTP 通信。传统Ajax 指的是 XMLHttpRequest(XHR),最早出现的向后端发送请求的技术,隶属于原始 JS 中, 核心使用 XMLHttpRequest 对象。它可以使用JSON、XML、HTML和text文本等格式发送和接收数据,多个请求之间如果有先后关系的话,就会出现回调地狱,它的主要好处是可以在不刷新页面的情况下,向后端发起请

简单的 HTTP 请求

let xhr = new XMLHttpRequest();
xhr.open('GET', '/url', true);
xhr.send();

完整的 HTTP 请求

let xhr = new XMLHttpRequest();
// 请求成功回调函数
xhr.onload = e => {
    console.log('request success');
};
// 请求结束
xhr.onloadend = e => {
    console.log('request loadend');
};
// 请求出错
xhr.onerror = e => {
    console.log('request error');
};
// 请求超时
xhr.ontimeout = e => {
    console.log('request timeout');
};

xhr.timeout = 0; // 设置超时时间,0表示永不超时
// 初始化请求
xhr.open('GET/POST/DELETE/...', '/url', true || false);
// 设置期望的返回数据类型 'json' 'text' 'document' ...
xhr.responseType = '';
// 设置请求头
xhr.setRequestHeader('', '');
// 发送请求,参数可以不传,可以是表单数据,可以是拼接在url后的数据,可以是json串
xhr.send(null || new FormData || 'a=1&b=2' || 'json字符串');

// 请求回调函数.XMLHttpRequest标准又分为Level 1和Level 2,这是Level 1和的回调处理方式
 xhr.onreadystatechange = () => {
    if (xhr.readyState !== 4) {
      return;
    }
    const status = xhr.status;
    if ((status >= 200 && status < 300) || status === 304) {
      console.log('request success');
    } else {
      console.log('request error');
    }
  };

JQuery ajax

为了更快捷的操作DOM,并且规避一些浏览器兼容问题,产生了jQuery。它里面的AJAX请求也兼容了各浏览器,可以有简单易用的方法$.get$.post。简单点说,就是对XMLHttpRequest对象的封装。

$.ajax({
  type: "POST",
  url: url, 
  data: data,
  dataType: dataType,
  success: function () {},
  error: function () {}
})

随着前后端技术的发展,jquery几乎不会再使用,对于一些老项目还会在用,jquery的缺点

  1. 如果有多个请求,并且有依赖关系的话,容易形成回调地狱。
  2. 本身是针对MVC的编程,不符合现在前端MVVM的浪潮。
  3. ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery非常的不合理。

Axios

Axios是一个基于promiseHTTP库,可以用在浏览器和 node.js 中。它本质也是对原生XMLHttpRequest的封装,只不过它是Promise的实现版本,符合最新的ES规范。

const axios = require('axios')

// Make a request for a user with a given ID
axios.get('/url', {params})    // or axios.post ...
        .then(function(response){
                console.log(response)
        })
        .catch(function(error){
           console.log(error) 
        })

// Want to use async/await? Add the `async` keyword to your outer function/method
async function getUser(){
    try{
        const response = await axios.get('/user')
        console.log(response)                   
    }catch(error){
         console.error(error)  
    }  
}

async/await 是ES6 中的内容,在 IE 及一些老版本的浏览器不支持,请谨慎使用。axios 的优点

  1. 从浏览器中创建XMLHttpRequest
  2. 支持 Promise API
  3. 客户端支持防止 CSRF
  4. 提供了一些并发请求的接口(重要,方便了很多的操作)
  5. 拦截请求和响应
  6. 转换请求和响应数据

防止CSRF(跨站请求伪造):就是让你的每个请求都带一个从cookie中拿到的key,根据浏览器同源策略,假冒的网站是拿不到你 cookie 中的key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。

fetch

fetch 号称是 AJAX 的替代品,是在 ES6 出现的,使用了ES6 中的 promise 对象。Fetch 是基于 promise 设计的。 Fetch 的代码结构比起 ajax 简单多了,fetch 不是 ajax的进一步封装,而是原生 JS , 没有使用 XMLHttpRequest 对象。

// 一个简单的fetch 请求
fetch('http://example.com/movies.json')
    .then(function(response){
        return response.json()
    })
    .then(function(myJson){
       console.log(myJson) 
    })


// 一个带有参数的fetch请求
postData('http://example.com/answer',{answer: 42})
    .then(data => console.log(data))  // JSON from 'response.json()' call
    .catch(error => console.error(error))

function postData(url, data) {
  // Default options are marked with *
  return fetch(url, {
       body: JSON.stringify(data),  // must match 'Content-Type' header
       cache: 'no-cache',  // * default, no-cache, reload, force-cache, only-if-cached
        headers: {
            'user-agent': 'Mozilla/4.0 MDN Example',
             'content-type': 'application/json'
        },
        method: 'POST', // *GET, POST, PUT, DELETE, etc.
        mode: 'cors', // no-cors, cors, *same-origin
        redirect: 'follow', // manual, *follow, error
        referrer: 'no-referrer', // *client, no-referrer    
  })    
  .then(response => response.json()) // parses response to JSON

由于fetch是原生的api,因此想要很好的使用fetch,需要做一些封装处理。fetch目前遇到的问题

  1. fetch只对网络请求报错,对400500都当做成功的请求,需要封装去处理
  2. fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
  3. fetch不支持abort,不支持超时控制,使用setTimeoutPromise.reject的实现超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费。
  4. fetch没有办法原生监测请求的进度,而XHR可以。

Author: 顺坚
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source 顺坚 !
评论
 Previous
利弗莫尔关键点交易法 利弗莫尔关键点交易法
利弗莫尔关键点交易法包括支撑,阻力的交易,突破交易。至今西方仍有大量交易员仅仅依靠支撑阻力位交易而取得过人业绩。要想灵活运用支撑与阻力获利,必须要了解支撑与阻力形成的真正原因,同其它的技术分析的根源一样,它们都是心理因素造成的。除阻力和支持
2021-11-13
Next 
WebGL与three.js WebGL与three.js
WebGL (全写Web Graphics Library) 是一种3D绘图协议,并提供了JavaScript API,,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0(OpenGL for Embedded Sys
2021-10-24
  TOC