Talk about several methods of front-end requests

introduction

The front-end is a rapidly developing field, and in the front-end technology stack, front-end requests are the most common field. Only by requesting interface data can a static page be made dynamic. This article will use the timeline of front-end development to analyze the technical evolution of front-end requests and their advantages and disadvantages one by one.

1. XMLHttpRequest

XMLHttpRequest is the earliest solution to exchange data with the server. With XMLHttpRequest, developers can finally update the webpage without reloading the page, and can request to accept and send data after the page is loaded. And all browsers can get the XMLHttpRequest object:

var xhr = new XMLHttpRequest(); //获取xhr对象

However, XMLHttpRequest is a rough underlying object, and different browsers create it in different ways. The following are compatible methods:

var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    xhr = new ActiveXObject('Msxml2.XMLHTTP');
  } catch (e) {
    try {
      xhr = new ActiveXObject('Microsoft.XMLHTTP');  //IE5,6
    } catch (e) {}
  }
}

Use XMLHttpRequest to initiate a get request:

//get请求
xhr.open("GET","test1.txt",true);
xhr.send();

The complete post request code is as follows:

var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    xhr = new ActiveXObject('Msxml2.XMLHTTP');
  } catch (e) {
    try {
      xhr = new ActiveXObject('Microsoft.XMLHTTP');
    } catch (e) {}
  }
}
if (xhr) {
  xhr.onreadystatechange = onReadyStateChange;
  xhr.open('POST', '/api', true);
  // 设置 Content-Type 为 application/x-www-form-urlencoded
  // 以表单的形式传递数据
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('username=admin&password=root');
}


// onreadystatechange 方法
function onReadyStateChange() {
  // 该函数会被调用四次
  if (xhr.readyState === 4 &&xhr.status === 200) {
    console.log('执行成功');
  } else {
    console.log('执行出错');
  }
}

2. Jquery Ajax

Speaking of Jquery, this is an era that has dominated the front-end for more than 10 years and completely solved the problem of interaction between the UI layer and the data layer. Until the emergence of the three major frameworks (Angular/React/Vue), the front-end entered the MVVM wave. Ajax encapsulates XHR so that developers can use it more conveniently.

$.ajax({   //标准写法
   type: 'POST',
   url: url,
   data: data,
   dataType: dataType,
   success: function () {},
   error: function () {}
});
$.get(url,function(){}); //get请求
$.post(url,body,function(){}); //post请求
$.getJSON(url,function(){});  //get请求从服务器加载Json编码

Advantages: - Encapsulation of native XHR - Programming for MVC - Perfect compatibility - Support jsonp

Disadvantages: - Does not conform to MVVM - The asynchronous model is not modern enough, does not support chaining, and the code readability is poor - The entire Jquery is too large and the introduction cost is too high

3. Fetch

Fetch is actually a new world. The detached XHR is completely asynchronous processing mechanism based on Promise, which is easier to use than ajax.

The code using fetch will be more organized than xhr, like this:

fetch(url).then(function(response) {
  return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function(e) {
  console.log("Oops, error");
});

Especially after using arrow functions:

fetch(url).then(response => response.json())
  .then(data => console.log(data))
  .catch(e => console.log("Oops, error", e))

Advantages: - More low-level, providing rich APIs (request, response) - Simple syntax, separated from XHR, based on the new Promise design of ES

Seeing the above, you may think that fetch is really beautiful, but please understand that fetch itself is a low-level API, and it is destined not to help you encapsulate various libraries like $.ajax or axios that you are used to. Such function or implementation.

So it has certain disadvantages: - Compatibility is relatively poor, low-level browsers do not support it, and the polyfill of fetch needs to be implemented. The idea is actually very simple, which is to judge whether the browser supports native fetch. If it does not support it, it will still use XMLHttpRequest to implement it, and combine it with Promise for packaging. Common polyfills include: es6-promise, babel-polyfill, fetch-ie8, etc.

  • Does not support jsonp, you can introduce fetch-jsonp
//安装
npm install fetch-jsonp --save-dev

//使用
fetchJsonp(url, {
  timeout: 3000,
  jsonpCallback: 'callback'
}).then(function(response) {
  console.log(response.json());
}).catch(function(e) {
  console.log(e)
});
  • Without an interceptor, an additional layer of encapsulation or fetch-interceptor is required
  • By default, there is no cookie, you need to add configuration
fetch(url,{
  credentials: 'include' //include表示cookie既可同域,也可跨域,‘same-origin’表示只可同域
});
  • No abort, does not support timeout timeout processing

It can be implemented with Promise.race(). The Promise.race(iterable) method returns a Promise object. As long as any Promise in the iterable is resolved or rejected, the external Promise will be resolved or rejected with the same value. - Unable to get progress status

The getReader() method is implemented in Response.body in fetch to read the original byte stream, which can be read cyclically. Refer javascript - Progress indicators for fetch? - Stack Overflow  2016 - the year of web streams

4. Axios

Axios is also a relatively new class library for network requests, and was recommended by You Yuxi Youda. It has become the standard configuration of VUE's network requests, and it is also very popular. It is itself a wrapper around native XHR. - Support node, create http request - Support Promise API - Client prevents CSRF: each request takes a key obtained by cookie - Intercept request and response - Cancellation request

In terms of compatibility, although axios is essentially an encapsulation of native XHR, it also relies on the implementation of native ES6 Promise, and requires polyfill compatibility just like fetch.

 Install:

//npm
npm install axios

//cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"><\/script>

The basic usage is as follows:

axios({
    method: 'GET',
    url: url,
})
.then(res => {console.log(res)})
.catch(err => {console.log(err)})

// get请求
axios.get(url)
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// post请求
axios.post(‘/user’, {
    name: 'Jerry',
    lastName: 'Liang'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

 

Handling of special scenarios

During the development process, we often encounter an embarrassing scenario, which is the serial and concurrency of multiple requests. Concurrency is easier to solve. There is no callback hell, but the readability of the code will easily become sloppy, and the serial problem is for The front end is desperate. The best way is to do the merge at the back end. If the back end does not do this, the front end has to face callback hell.

multiple request serial

// ajax
$.ajax({
    url: '',
    data: '',
    success: function (data) {
       $.ajax({
            url: '',
            data: '',
            success: function (data) {
                $.ajax({
                    // 如此一层嵌套一层
                })
            }
        }) 
    }
})

//axios
axios.get(url)
.then(res => {
    return axios.get(url,{
         {name:result.name}
    });
}).then(res => {
    //如此一层层嵌套
});

Multiple requests in parallel

//ajax 通过计数器实现(虽然Jquery支持$.when的方式,但此处不做案例)
var num = 0;
function all(){
    num++;
    if(n>=3)console.log('三个请求全部完成');
}
$.ajax({
    url: '',
    data: '',
    success: function (data) {
       console.log("ajax请求1 完成");
       all();
    }
})
$.ajax({
    url: '',
    data: '',
    success: function (data) {
       console.log("ajax请求2 完成");
       all();
    }
})
$.ajax({
    url: '',
    data: '',
    success: function (data) {
       console.log("ajax请求3 完成");
       all();
    }
})

//axios
function getInfo() {
  return axios.get(url);
}
function getUser() {
  return axios.get(url);
}
axios.all([getInfo(), getUser()])
  .then(axios.spread(function (info, user) {
    // 两个请求现在都执行完成
  }));

 

How to choose (personal understanding, for reference only)

  1. First of all, it is certain that if your code is still based on Jquery, then there is no doubt that ajax is your best choice.
  2. If you are using any MVVM framework, it is recommended to use axios without thinking. In actual project use, fetch requires various encapsulation and exception handling, which is not available out of the box, and axios can directly replace $.ajax.
  3. If you want to use fetch, then I believe you will be able to encapsulate it into your own set of best practices.

Reference: [Research and Summary] Those things about front-end requests (xhr/ajax/fetch/axios) - Know almost

Guess you like

Origin blog.csdn.net/BUG_CONQUEROR_LI/article/details/129600428