Still worrying about mastering Ajax? Read this article and you will find all the answers for Ajax

    JS series 8.0 is mainly AJAX summary and practice,this article describes the basic knowledge of Ajax in detail, including basic Ajax requests, encapsulation of Ajax requests, request data format issues, status codes, etc. In addition, it also involves cross-domain issues and implementation issues of Ajax interceptors, and cites specific examples to deepen understanding study

    1 Overview

    1. Ajax It is a set of methods provided by the browser, which can update data without refreshing the page, and improve the experience of users browsing website applications.
    2. Application scenarios:

      • Pull up the page to load more data
      • no refresh pagination
      • Form item out of focus data validation
      • Search box prompt text drop-down list
    3. Disadvantage: Ajax itself does not support cross-domain requests


    2. The basic process of ajax request

    var xhr = new XMLHttpRequest();
    xhr.open('method','url',async(can be omitted));
    xhr. send();
    xhr.onload = function (){}
    

    2.1 Create ajax object

    var xhr = new XMLHttpRequest()
    

    2.2 Set Request

    xhr.open(method,url,async): ajax request method: get or post, and the request address url, whether it is asynchronous async (default is true) and it is not recommended to change async to false, the user experience will be very bad difference

    Use post request

    Note: If you use the post method, you must set the parameter format type of the request, .setRequestHeader(header, value)
    header: The name of the attribute.
    value: The value of the attribute.

    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    

    When using setRequestHeader() after open(), before send()
    Place the request parameters in different positions when making an Ajax request: put the get behind the request address, and put the post in the send method

    Send form type data:

    ('Content-Type', 'application/x-www-form-urlencoded')
    Data format: name=Xiaoming&age=20

    xhr.send('username=admin&age=18')

    Send data of JSON type: (to convert the json object to json string, because the request parameters must be passed in string format)

    ('Content-Type', 'application/json')
    Data format: {name: 'Xiao Ming', age: '20'}
    xhr.send(JSON.stringify({name: 'admin', age:18}));

    2.3 Send request

    xhr.send()
    

    2.4 Get the data from the server to the client

    xhr.onload = function (){
    console.log(xhr.responseText)
      // xhr.responseText receives response data in text format
     // xhr.responseXML receives response data in xml format
    }
    


    3. Data format

    3.1 JSON. parse()

    1. In the process of http request and response, whether it is the request parameter or the response content, if it is an object type, it will eventually be converted into object string for transmission, so JSON.parse() should be used to obtainreturn to json object

      JSON.parse() // convert json string to json object
      

    3.2 JSON.stringify()

    1. Note: the get request cannot submit the json object data format, it must be converted into a json string JSON.stringify() // convert json object to json string

      Number Infinity and NaN and value null will be converted to null when using JSON.stringify()

      JSON.stringify([NaN, null, Infinity]); // '[null,null,null]'

    2. JSON.stringify() and localStorage access

       const session = {
        'screens': [
        { 'name': 'screenA', 'width': 450, 'height': 250 },
        { 'name': 'screenB', 'width': 650, 'height': 350 },
        { 'name': 'screenC', 'width': 750, 'height': 120 }
        ],
        'state': true
      };
       localStorage.setItem('session',JSON.stringify(session) );
       const restoredSession = JSON.parse(localStorage.getItem('session'));
       console.log(restoredSession);
      

    If you don't use JSON.stringify() to save data and JSON.parse() to get data:

    localStorage.setItem('session', session);
    const restoredSession = localStorage.getItem('session');
    console.log(restoredSession);
    

    If you do not use JSON.parse() to fetch data when fetching data

    localStorage.setItem('session', JSON.stringify( session));
    const restoredSession = localStorage.getItem('session');
    console.log(restoredSession);
    

    If JSON.stringify() is not used when saving data, an error will be reported


    4. Ajax status code

    • 0: the request is uninitialized (open() has not been called yet)
    • 1: Loading: server connection established but not yet sent (open has been called, send() has not been called yet)
    • 2: The request has been sent and loaded
    • 3: The request is being processed, usually some data is already available in the response
    • 4: The response has been completed, and the response from the server can be obtained and used

    xhr.readyState // get Ajax status code
    xhr.onprogress is when the status code is 3, you can write loading animation and other effects at this time, such as the small dot loading when the page jumps, xhr.onprogress is a non-required function

    xhr.onprogress = function(){
       console.log('READYSTATE: ', xhr.readyState);
    }
    


    Common status codes

    • 200 indicates that the request sent from the client is processed normally on the server side
    • 204 indicates that the request was processed successfully, but no resources were returned.
    • 301 means a permanent redirect. This status code indicates that the requested resource has been assigned a new URI and that the URI to which the resource now refers should be used in the future.
    • 302 indicates a temporary redirect.
    • 401 means Unauthorized, the current request requires user authentication
    • 403 means the server rejected the request
    • 404 means the server could not find the requested page
    • 503 means the server is temporarily overloaded or under maintenance and unable to process the request.


    5. The difference between onreadystatechange event and onload event

    onreadystatechange :
    When the Ajax status code changes, the onreadystatechange event will be triggered automatically. When the status code is 4, the server-side response data can be obtained through xhr.responseText.

    // When the Ajax status code changes
    xhr.onreadystatechange = function () {
    // Judge when the Ajax status code is 4
    if (this. readyState == 4 && this. status == 200) {
    // Get the response data from the server
    console.log(xhr.responseText);
    }
    }
    

    Use onreadystatechange to print status code 2, 3, 4

    onload:
    Only when it is in status code 4, that is, when the response is ready, it will enter onload. Using onload only prints status code 4


    6. Ajax error handling

    xhr.onerror = function () {
    alert('Ajax request error')
    }
    //This event is triggered when the request encounters an error
    
    1. The network is smooth, the server can receive the request, but the result returned by the server is not the expected result. Use xhr.status to get the http status code for troubleshooting
    2. The network is smooth, the server does not receive the request, and returns a 404 status code: check whether the request address is wrong.
    3. The network is smooth, the server can receive the request, and the server returns a status code of 500: server error, and communicate with the back-end programmer.

    7. Ajax example application

    Note: If you use a local file to debug ajax, you can use open with live server to open it, otherwise an error will be reported, because the browser thinks this method is not safe, and it will be regarded as a cross-site attack and will block the request
    Recommend an ajax interface website that can request data for free for testing: FillText.com


    7.1 ajax get plain text

    <button id="button">get plain text</button>
    <br><br>
    <div id="text"></div>
    
    <script>
    document.getElementById('button').addEventListener('click', loadText);
    function loadText(){
      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'sample.txt');
      xhr.onload = function(){
        console.log('READYSTATE: ', xhr.readyState);
        if(this.status == 200){
          document.getElementById('text').innerHTML = this.responseText;
        } else if(this.status = 404){
          document.getElementById('text').innerHTML = 'Not Found';
        }
      }
    
      xhr.onerror = function(){
        console.log('request error');
      }
        xhr.send();
    }
     </script>
    

    If you change to a text file that does not exist, an error will be reported xhr.open('GET', 'sample2.txt');

    7.2 ajax get local JSON file

    <body>
    <button id="button">Get Users</button>
    <h1>Users</h1>
    <div id="users"></div>
    <script>
        document.getElementById('button').addEventListener('click', loadUsers);
        function loadUsers() {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'users.json');
            xhr.onload = function () {
                    var users = JSON.parse(this.responseText);
                    var output = '';
                    for (var i in users) {
                         output += `
                        <ul>
                        <li>ID:${users[i].id}</li>
                        <li>Name: ${users[i].name}</li>
                         </ul>
          `;
                    }
                    document.getElementById('users').innerHTML = output;
            };
            xhr.send();
        }
    </script>
    </body>
    

    JSON file:

    [
      {
    "id":1,
    "name":"Rick"
      },
      {
    "id":2,
    "name":"Wang"
      },
      {
    "id":3,
    "name":"Fang"
      }
    ]
    

    7.3 ajax get external link api

    <script>
    document.getElementById('button').addEventListener('click', loadUsers);
    function loadUsers(){
      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'http://www.filltext.com/?rows=6&fname={firstName}&lname={lastName}');
      xhr.onload = function(){
          var users = JSON.parse(this.responseText);
          console.log(users);
          var output = '';
          for(var i in users){
            output +=
              '<div class="user">' +
              '<ul>' +
              '<li>fname: '+users[i].fname+'</li>' +
              '<li>lname: '+users[i].lname+'</li>' +
              '</ul>' +
              '</div>';
          }
    
          document.getElementById('users').innerHTML = output;
      }
    
      xhr.send();
    }
    </script>
    


    7.4 Using ajax in jquery

    $('#btn').on('click', function () {
    $.ajax({
       type: 'post',
       url: '',
       // Request parameters sent to the server
    data: JSON.stringify(params),
       success: function (xhr) {
     console. log(xhr);
       }
    })
    });
    


    8. ajax package

    Object.assign(target, ...sources):
    target: The target object, the object that receives the properties of the source object, is also the modified return value.
    sources: The source object, containing the attributes that will be merged.
    If the target object has the same key as the source object, the properties in the target object will be overwritten by the properties in the source object, and the properties of the later source objects will similarly override the properties of the previous source objects.

    Package:

    <script>
    function ajax (options) {
    // stores the default value
    var defaults = {
    type: 'get',
    url: '',
    data: {},
    header: {
    'Content-Type': 'application/x-www-form-urlencoded'
    },
    success: function () {},
    error: function () {}
    };
    
    // Use the properties in the options object to override the properties in the defaults object
    Object. assign(defaults, options);
    var xhr = new XMLHttpRequest();
    // Variables for splicing request parameters
    var params = '';
    // Circulate the parameters passed by the user, that is, the loop traversal and value of the object
    for (var value in defaults. data) {
    // convert the parameter to string format
    params += value + '=' + defaults.data[value] + '&';
    //value is the object attribute name, defaults.data[value] is the corresponding attribute value
    }
    // Intercept the & at the end of the parameter
    params = params.substr(0, params.length - 1);
    // Determine the request method
    if (defaults. type == 'get') {
    defaults.url = defaults.url + '?' + params;
    }
    // configure the ajax object
    xhr.open(defaults.type, defaults.url);
    // If the request method is post
    if (defaults. type == 'post') {
    // Set the type of request parameter format
    var contentType = defaults. header['Content-Type']
    //xhr.setRequestHeader after xhr.open, before xhr.send
    xhr.setRequestHeader('Content-Type', contentType);
    // if the type is json
    if (contentType == 'application/json') {
    xhr.send(JSON.stringify(defaults.data))
    } else {
    // Pass request parameters of common types to the server
    xhr. send(params);
    }
    }
    else {
    // send get request
    xhr. send();
    }
    
    // Triggered when the xhr object has received the response data
    xhr.onload = function () {
    // Get the data type in the response header
    var contentType = xhr. getResponseHeader('Content-Type');
    // The data returned by the server
    var responseText = xhr. responseText;
    // if the response type is json
    if (contentType. includes('application/json')) {
    // convert json string to json object
    responseText = JSON. parse(responseText)
    }
    if (xhr. status == 200) {
    // The request is successful Call the function that handles the success
    defaults.success(responseText, xhr);
    } else {
    // The request failed, call the function that handles the failure
    defaults.error(responseText, xhr);
    }
    }
    // when the network is interrupted
    xhr.onerror = function () {
    // Call the failure callback function and pass the xhr object to the callback function
    defaults. error(xhr);
    }
    }
    </script>
    

    use:

    <body>
    <script  src="/js/ajax.js"></script>
    <script type="text/javascript">
    ajax({
    url: '',
    type: '',
    success: function(data) {
     console.log(data)  
    }
    })
    </script>
    </body>
    


    9. Cross-domain problem solving

    1. Cross-domain through jsonp
    2. Cross-Origin Resource Sharing (CORS)
    3. location.hash + iframe
    4. window.name + iframe cross domain
    5. postMessage cross-domain
    6. document.domain + iframe cross-domain
    7. nginx proxy cross-domain
    8. Nodejs middleware proxy cross-domain
    9. Cross-domain WebSocket protocol
      I will write a blog post in detail later


    10. Use ajax to implement interceptors

    The interceptor setting allows us to do some things before sending a request or receiving a response, such as changing the data format of the response, or adding different configs according to different requests, etc. The request interceptor is the operation performed before the request is sent, such as setting whether a token is required; the response interceptor is the operation after receiving the response, such as setting the response failure jump through the status code, etc.

    10.1. Native AJAX implementation interceptor

    The send method needs to be changed, XMLHttpRequest.prototype.send redefines the send function in its prototype.

    const intercept = (method, url, requestCallback, responseCallback) => {
        let xhr = new XMLHttpRequest();
        // Modify the prototype's open and send methods to create request and response interceptors
        let open = XMLHttpRequest.prototype.open;
        let send = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.open = function () {
          requestCallback();
          open. call(this, method, url);
        };
    
        XMLHttpRequest.prototype.send = function () {
          //Called when the Ajax status code changes
          this.addEventListener('readystatechange', function () {
            //The function called when the request is successful, or when other status codes can be set
            if (this.readyState === 4 && this.status === 200) {
              //Response interceptor, return useful data
              let response = JSON. parse(this. responseText);
              responseCallback(response. data);
            }
          });
          send.apply(this, arguments); //Change the calling object of the send function
        };
        xhr.open();
        xhr. send();
      };
    
      let foo = function () {
        console.log('The operation of sending the request');
      };
      let fn = function (data) {
        //The return value after processing the response data
        console. log(data);
      };
    
      //use
      intercept('get', 'https://reqres.in/api/products/4', foo, fn)
    

    result:

    The complete code of multiple ajax interceptors can be passed in: GitHub


    10.2. Use JQ's ajax to implement the interceptor

    You can call the api that comes with jQuery: $.ajaxSetup and beforeSend

    $.ajaxSetup({
         url: 'https://reqres.in/api/users/3', //test interface, can be used directly
         // This function will be run before the request is sent
         beforeSend() {
           console.log('Operation before sending the request');
         },
         dataFilter: function (data, type) {
           data = JSON. parse(data);
           console. log(data);
         //Process the response data and directly return the useful data in the response data
           return JSON. stringify(data. data)
         },
         success: function (data) {
             //Get the data in the response data
           console. log(data);
         },
       });
       //Call ajax, you can pass in your own set url, type, success, error,
       // But the default values of async, headers and other parameters have been changed by $.ajaxSetup()
       $.ajax({
         url: 'https://reqres.in/api/products/3'
       });
    

    The settings of the $.ajaxSetup() method will be applied to the global AJAX properties of the entire page
    beforeSend : This event fires before the Ajax request starts, allowing you to modify the XMLHttpRequest object (like setting additional headers, etc.)
    dataFilter: Function for processing raw response data of XMLHttpRequest. This is a pre-filter function to sanitize the response
    complete: function to be called when the request is complete (after success and error callbacks are executed)

    Popular posts from this blog

    大学资料分享——广工计院各个科目实验报告、课设及期末复习资料!!

    Win10 远程计算机或设备将不接受连接

    JAVA Traffic Signal Light Course Design (Source Code + Report + Video Demonstration)

    Implementation of Ajax Interceptor