Native JavaScript realizes AJAX and JSONP

  • 2021-07-18 06:28:03
  • OfStack

It is believed that most front-end developers will choose AJAX method encapsulated in JQuery for convenience and speed when they need to interact with back-end data. However, sometimes, we only need AJAX request method of JQuery, and other functions are rarely used, which is obviously unnecessary.

In fact, it is not difficult to implement AJAX with native JavaScript. This article will explain how to implement simple AJAX and cross-domain request JSONP!

1. AJAX

The core of AJAX is XMLHttpRequest.

A complete AJAX request 1 generally includes the following steps:

Instantiating an XMLHttpRequest object Connect to the server Send a request Receive response data

I encapsulate the AJAX request as an ajax () method, which accepts a configuration object, params.


function ajax(params) {  
 params = params || {};  
 params.data = params.data || {};  
 //  Judge is ajax Request or jsonp Request 
 var json = params.jsonp ? jsonp(params) : json(params);  
 // ajax Request   
 function json(params) {  
  //  Request method, default is GET
  params.type = (params.type || 'GET').toUpperCase(); 
  //  Avoid special characters, and you must format the transmitted data  
  params.data = formatParams(params.data);  
  var xhr = null;  
  //  Instantiation XMLHttpRequest Object   
  if(window.XMLHttpRequest) {  
   xhr = new XMLHttpRequest();  
  } else {  
   // IE6 And its following versions   
   xhr = new ActiveXObjcet('Microsoft.XMLHTTP');  
  }; 
       //  Listen for events, as long as  readyState  Is changed, a call is made to the  readystatechange  Events 
  xhr.onreadystatechange = function() { 
   // readyState Property represents a request / The current active phase of the response process, 4 To complete, all response data has been received 
   if(xhr.readyState == 4) {  
    var status = xhr.status; 
    // status Responsive HTTP Status code to 2 The beginning is all success 
    if(status >= 200 && status < 300) {  
     var response = ''; 
     //  Determining the content type of the accepted data  
     var type = xhr.getResponseHeader('Content-type');  
     if(type.indexOf('xml') !== -1 && xhr.responseXML) {  
      response = xhr.responseXML; //Document Object response   
     } else if(type === 'application/json') {  
      response = JSON.parse(xhr.responseText); //JSON Response   
     } else {  
      response = xhr.responseText; // String response   
     }; 
     //  Successful callback function  
     params.success && params.success(response);  
    } else {  
     params.error && params.error(status);  
    }  
   };  
  }; 
  //  Connecting and transmitting data   
  if(params.type == 'GET') {
   // 3 Parameters: Request method, request address (get Mode, the transmission data is added after the address ) Whether the request is asynchronous or not ( Synchronization requests are rare ) ; 
   xhr.open(params.type, params.url + '?' + params.data, true);  
   xhr.send(null);  
  } else {  
   xhr.open(params.type, params.url, true);  
   // Must, set the content type when submitting   
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 
   //  Transmit data  
   xhr.send(params.data);  
  }  
 } 
 // Formatting parameters   
 function formatParams(data) {  
  var arr = [];  
  for(var name in data) { 
   //  encodeURIComponent()  : Used for the  URI  One of 1 Partially encoding 
   arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));  
  };  
  //  Add 1 Random number parameters to prevent caching   
  arr.push('v=' + random());  
  return arr.join('&');  
 }
 //  Get random number   
 function random() {  
  return Math.floor(Math.random() * 10000 + 500);  
 }
}

In the above code, the value of readyState represents the current active phase of the request/response process, and its value means the following:

0: For initialization. The open () method has not been called.

1: Start. The open method has been called, but the send () method has not been called.

2: Send. The send () method has been called, but no response has been received.

3: Receive. Partial response data has been received.

4: Done. All response data has been received and can be used on the client

Use example:


ajax({  
 url: 'test.php',  //  Request address 
 type: 'POST',  //  Request type, default "GET" , it can also be "POST"
 data: {'b': ' Asynchronous request '},  //  Transmit data 
 success: function(res){  //  Request successful callback function 
  console.log(JSON.parse(res));  
 },
 error: function(error) {}  //  Request failed callback function 
});

2. JSONP

Homologous strategy

The reason why AJAX needs to be "cross-domain" is the browser's homology strategy. That is, an AJAX for 1 page can only get data from the same source or the same domain for this page. How to call it "homologous" or "homologous"? -The protocol, domain name and port number must all be the same. For example

http://example.com and https://example.com are different because of different protocols;

http://localhost: 8080 and http://localhost: 1000 are different because of different ports;

http://localhost: 8080 is different from https://example. com, with different protocols, domain names and port numbers, so it is not one at all.

1 will generally see this error when requesting across domains:

XMLHttpRequest cannot load http://ghmagical.com/article/?intro=jsonp%E8%AF%B7%E6%B1%82 & v=5520. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

How do you request across domains? At this time, JSONP appeared!

JSONP is short for JSON with Padding (filled JSON or parametric JSON), which is a very common cross-domain request method. The main principle is that script tag can request across domains, and its src attribute sends a request to the server, the server returns JavaScript code, the browser accepts the response, and then executes it directly, which is the same as the principle of referencing external files through script tag.

JSONP consists of two parts: callback function and data. Callback function is the function that should be called in the page when the response arrives. The name of callback function 1 is specified in the request. When the server responds, the server will spell the function and data into a string and return it.

The request process for JSONP:

Request phase: The browser creates an script tag and assigns its src value (similar to http://example.com/api/? callback=jsonpCallback). Send Request: When src of script is assigned a value, the browser initiates a request. Data response: The server returns the data to be returned as a parameter and function name spliced in 1 (format similar to "jsonpCallback ({name: 'abc'})"). When the browser receives the response data, since the request is made by script, it is equivalent to calling the jsonpCallback method directly and passing in 1 parameter.

Here, explain how to realize it with native JavaScript.

JSONP is still added to ajax () method, and the two will be integrated into one later. The configuration parameter of JSONP is mainly added with one jsonp parameter, which is your callback function name.


function ajax(params) {  
 params = params || {};  
 params.data = params.data || {};  
 var json = params.jsonp ? jsonp(params) : json(params);   
 // jsonp Request   
 function jsonp(params) {  
  // Create script Tag and add it to the page   
  var callbackName = params.jsonp;  
  var head = document.getElementsByTagName('head')[0];  
  //  Set the callback parameter name passed to the background   
  params.data['callback'] = callbackName;  
  var data = formatParams(params.data);  
  var script = document.createElement('script');  
  head.appendChild(script);  
  // Create jsonp Callback function   
  window[callbackName] = function(json) {  
  head.removeChild(script);  
  clearTimeout(script.timer);  
  window[callbackName] = null;  
  params.success && params.success(json);  
  };  
    // Send a request   
  script.src = params.url + '?' + data;  
  // In order to know whether this request was successful, set a timeout processing   
  if(params.time) {  
   script.timer = setTimeout(function() {  
    window[callbackName] = null;  
    head.removeChild(script);  
    params.error && params.error({  
     message: ' Timeout '  
    });  
   }, time);  
  }  
 };  
 // Formatting parameters   
 function formatParams(data) {  
  var arr = [];  
  for(var name in data) {  
   arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));  
  };  
  //  Add 1 Random number to prevent caching   
  arr.push('v=' + random()); 
  return arr.join('&');  
 }  
 //  Get random number   
 function random() {  
  return Math.floor(Math.random() * 10000 + 500);  
 }
}

Note: Because the src attribute of the script tag only works when it is set for the first time, the script tag cannot be reused, so it should be removed after each operation;

Use example:


ajax({  
  url: 'test',  //  Request address 
 jsonp: 'jsonpCallback', //  Adopt jsonp Request, and the callback function is named "jsonpCallbak" Which can be set to a legal string 
 data: {'b': ' Asynchronous request '},  //  Transmit data 
 success:function(res){  //  Request successful callback function 
  console.log(res);  
 },
 error: function(error) {}  //  Request failed callback function 
});

Although JSONP is very simple and easy to use, it also has two disadvantages

JSONP is executed by loading code from other domains. If other domains are unsafe, they may carry some malicious code. At this time, there is no way to investigate except to give up the call of JSONP completely It is not easy to confirm whether the JSONP request failed

Related articles: