Asynchronous request Ajax implementation in Javascrpit

Source: Internet
Author: User



In the process of front-end page development, you often use AJAX requests to submit form data asynchronously, or to refresh the page asynchronously.



In general, it is very convenient to use $.ajax,$.post,$.getjson in jquery, but sometimes it is not a good deal to introduce jquery only because of the need for AJAX functionality.



So the next step is to implement a simple Ajax request with the native Javascrpit, and explain the cross-domain access problem in the AJAX request, as well as the data synchronization of multiple AJAX requests.


JavaScript implementation of Ajax asynchronous request simple Ajax request implementation


The principle of an AJAX request is to create a XMLHttpRequest object that uses this object to send the request asynchronously, using the following code:

function ajax (option) {
    // Create an XMLHttpRequest object
    var xhr = window.XMLHttpRequest? new XMLHttpRequest (): new ActiveXObject ("Microsoft.XMLHTTP"),
        requestData = option.data,
        requestUrl = option.url,
        requestMethod = option.method;
    // If it is a GET request, you need to splice the parameters in the option behind the URL
    if (‘POST’! = requestMethod && requestData) {
        var query_string = ‘‘;
        // Traverse the option.data object and construct GET query parameters
        for (var item in requestData) {
            query_string + = item + ‘=‘ + requestData [item] + ‘&‘;
        }
        // Note that when splicing here, you need to judge whether there is already?
        requestUrl.indexOf (‘?‘)> -1
            ? requestUrl = requestUrl + ‘&‘ + query_string
            : requestUrl = requestUrl + ‘?’ + query_string;
        // GET request parameters are placed in the URL, leaving requestData blank
        requestData = null;
    }
    // callback function after successful ajax request
    xhr.onreadystatechange = function () {
        // readyState = 4 means the response is accepted
        if (xhr.readyState == ("number" == typeof XMLHttpRequest.DONE? XMLHttpRequest.DONE: 4)) {
            if (200 == xhr.status) {// judge the status code
                var response = xhr.response || xhr.responseText || {}; // Get the return value
                // if define success callback, call it, if response is string, convert it to json objcet
                console.log (response);
                // Can determine the type of data returned, JSON analysis or XML analysis of the data
                // option.success && option.success (‘string‘ == typeof response? JSON.parse (response): response);
            } else {
                // if define error callback, call it
                option.error && option.error (xhr, xhr.statusText);
            }
        }
    };
    // send ajax request
    xhr.open (requestMethod, requestUrl, true);
    // Request timeout callback
    xhr.ontimeout = function () {
        option.timeout && option.timeout (xhr, xhr.statusText);
    };
    // Define timeout
    xhr.timeout = option.timeout || 0;
    // Set the response header. The default setting here is json format, which can be defined as other formats, just modify the header
    xhr.setRequestHeader && xhr.setRequestHeader (‘Content-Type’, ‘application / json; charset = utf-8‘);
    xhr.withCredentials = (option.xhrFields || {}). withCredentials;
    // This is mainly used to send POST request data
    xhr.send (requestData);
}
There are detailed comments in the above code. The principle of ajax is very simple. In general, it uses XMLHttpRequest object to send data. Here is a supplementary explanation of this object.

Basic properties of XMLHttpRequest object
The readyState attribute has five state values:

0: Yes uninitialized: Not initialized. The XMLHttpRequest object has been created but not initialized.
1: It is loading: it is ready to be sent.
2: Yes, it has been sent, but no response has been received.
3: Yes interactive: The response is being received, but it has not been received.
4: Yes completed: The response is accepted.
responseText: The response text returned by the server. Only when readyState> = 3 has value. When readyState = 3, the returned response text is incomplete, only readyState = 4, the complete response text is received. responseXML: The response information is xml, which can be parsed as a Dom object. status: Http status code of the server, if it is 200, it means OK, 404, it means that it is not found. statusText: The text of the server's http status code. For example OK, Not Found.

Basic methods of XMLHttpRequest object
open (method, url, asyn): Open the XMLHttpRequest object. Method methods include get, post, delete, and put. url is the address of the requested resource. The third parameter indicates whether to use asynchronous. The default is true, because Ajax is characterized by asynchronous transmission. False if using synchronization. send (body): send the request Ajax. The content sent can be the required parameters, if there is no parameter, directly send (null)

Instructions
Directly call the ajax function defined above, and transfer the corresponding options and parameters.

ajax ({
    url: ‘/post.php’,
    data: {
        name: ‘uusama’,
        desc: ‘smart’
    },
    method: ‘GET’,
    success: function (ret) {
        console.log (ret);
    }
});
Cross-domain request issues
When using ajax requests, you must pay attention to one problem: cross-domain requests. Without special measures, cross-domain requests: When requesting URL resources under other domain names and ports, an Access-Control-Allow-Origin-related error will be reported. The main reason is that the browser's same-origin policy is limited. Browsers stipulate that resources cannot be requested across domains.

Solution
Here are some simple solutions. Add headers that allow cross-domain requests in the ajax header. This method also requires the server to add headers that allow cross-domain requests. Here is an example of PHP adding PHP that allows POST requests to cross domain headers:

// Specify to allow other domain names to access
header (‘Access-Control-Allow-Origin: *‘);
// Response type
header (‘Access-Control-Allow-Methods: POST’);
// Response header setting
header (‘Access-Control-Allow-Headers: x-requested-with, content-type‘);
Use the dynamic scrpit tag to dynamically create a scrpit tag and point it to the requested address, which is the JSONP method. You need to stitch a callback function after the URL. The callback function will be called after the tag is loaded successfully.

var url = "http://uusama.com", callbaclName = ‘jsonpCallback’;
script = document.createElement (‘script‘);
script.type = ‘text / javascript’;
script.src = url + (url.indexOf (‘?‘)> -1? ‘&‘: ‘?’) + ‘callback =‘ + callbaclName;
document.body.appendChild (script);
The callback function needs to be set as a global function:

window [‘jsonpCallback‘] = function jsonpCallback (ret) {}
Multiple ajax request data synchronization problem A single ajax return data is processed asynchronously
Multiple ajax requests are not related to each other, they send their respective requests after being called, and call their own callback method after the request is successful, without affecting each other. Because of the asynchronous nature of ajax requests, all operations that depend on the completion of the request need to be placed inside the callback function, otherwise, the value you read outside the callback function is empty. See the example below:

var result = null;
ajax ({
    url: ‘/get.php?id=1‘,
    method: ‘GET’,
    success: function (ret) {
        result = ret;
    }
});
console.log (result); // output null
Although we set the result value in the callback function, the console.log (result); output is empty in the last line. Because the ajax request is asynchronous, when the program executes to the last line, the request is not completed, and the value has not been modified. Here we should put the processing related to console.log (result) in the success callback function.

Multiple ajax return data problem
If there are multiple ajax requests, the situation becomes a little more complicated. If multiple ajax requests are executed in order, and one of them is completed before proceeding to the next, you can put the latter request in the callback of the previous request. For example, there are two ajax requests, and the data of one request depends on the other, you can make an ajax request in the callback of the first request:

// First request the first ajax
ajax ({
    url: ‘/get1.php?id=1‘,
    success: function (ret1) {
        // After the first request is successfully called back, request the second one
        if (ret1) {
            ajax ({
                url: ‘/get2.php?id=4’,
                success: function (ret2) {
                    console.log (ret1);
                    console.log (ret2)
                }
            })
        }
    }
});

// can also be written in the following form
var ajax2 = function (ret1) {
    ajax ({
        url: ‘/get2.php?id=4’,
        success: function (ret2) {
            console.log (ret1);
            console.log (ret2)
        }
    });
};
ajax ({
    url: ‘/get1.php?id=1‘,
    success: function (ret1) {
        if (ret1) {
            ajax2 (ret1);
        }
    }
});
If you do not care about the order of different ajax requests, but only care about all the requests are completed, you can proceed to the next step. One method is to call the same callback function after each request is completed, and only perform the next step when the number of times is reduced to 0.

var count = 3, all_ret = []; // call 3 times
ajax ({
    url: ‘/get1.php?id=1‘,
    success: function (ret) {
        callback (ret);
    }
});
ajax ({
    url: ‘/get2.php?id=1‘,
    success: function (ret) {
        callback (ret);
    }
});
ajax ({
    url: ‘/get3.php?id=1‘,
    success: function (ret) {
        callback (ret);
    }
});
function callback (ret) {
    if (count> 0) {
        count--;
        // You can save ret to global variables here
        all_ret.push (ret);
        return;
    } else {// After calling three times
        // todo
        console.log (ret);
    }
}
Another method is to set a scheduled task to rotate whether all ajax requests are completed. You need to set a flag in each ajax success callback. Here you can judge by whether you get the value, or you can set the label to judge. When judging by the value, pay attention to the situation where the set value is the same as the initial value.

var all_ret = {
    ret1: null,
    ret2: null,
    ret3: null,
};
ajax ({
    url: ‘/get1.php?id=1‘,
    success: function (ret) {
        all_ret [‘ret1‘] = ret;
    }
});
ajax ({
    url: ‘/get2.php?id=1‘,
    success: function (ret) {
        all_ret [‘ret2‘] = ret;
    }
});
ajax ({
    url: ‘/get3.php?id=1‘,
    success: function (ret) {
        all_ret [‘ret3‘] = ret;
    }
});
var repeat = setInterval (function () {
    for (var item in all_ret) {
        if (all_ret [item] === null) {
            return;
        }
    }
    // todo, here all ajax requests have been completed
    clearInterval (repeat);
}, 50);
Original text from: http://uusama.com/377.html

Implementation of asynchronous request Ajax in JavaScrpit

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.