Native js implements Ajax and JSONP

Posted by mrtechguy on Tue, 10 Dec 2019 05:22:45 +0100

Several execution steps inside Ajax

  • Create XMLHttpRequest object (new XMLHttpRequest())
  • Set request header
  • Connect to server (open())
  • Set callback (onreadyStateChange)
  • Send data (send())
  • Get data in callback function

JSONP

script tags can be used to request resources across domains to solve cross domain problems. Detailed explanation can be seen Thoroughly understand cross domain problems

Front-end code

/*
* Native js implementation of Ajax
* */

function Ajax(params) {
    params = params || {};
    params.data = params.data || {};
    var _json = params.jsonp ? jsonp(params): json(params); // Judge whether it is json or json
    function json(params) { // Ordinary request
        params.type = (params.type || 'GET').toUpperCase(); // Set request default type
        var urlData = formatParams(params.data); // Format data
        var xhr = null; // Initialize xhr
        if (window.XMLHttpRequest) {
            xhr = new window.XMLHttpRequest();
        } else {
            xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }
        var headers = params.headers || {};
        if (params.type === 'GET') {
            xhr.open(params.type, params.url + '?' + urlData, true);
            setHeaders(xhr, headers);
            xhr.send(null);
        } else {
            xhr.open(params.type, params.url, true);
            setHeaders(xhr, headers);
            xhr.send(JSON.stringify(params.data));
        }
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                var status = xhr.status;
                if (status >= 200 && status < 300) {
                    var response = '';
                    var type = xhr.getResponseHeader('Content-Type');
                    if (type.indexOf('xml') !== -1 && xhr.responseXML) { // xml format
                        response = xhr.responseXML;
                    } else if (type.indexOf('application/json') !== -1) { // JSON format
                        response = JSON.parse(xhr.responseText);
                    } else {
                        response = xhr.responseText; // String format
                    }
                    params.success && params.success(response);
                } else {
                    params.error && params.error(status);
                }
            }
        }
    }
    function jsonp(params) {
        var callbackName = params.jsonp; // Callback function name
        var head = document.getElementsByTagName('head')[0];
        params.data['callback'] = callbackName;
        var data = formatParams(params.data);
        var script = document.createElement('script');
        head.appendChild(script);
        // Create a JSON function. After success, the success function will be called automatically and deleted automatically
        window[callbackName] = function (json) { // Set callback and execute only after getting background data
            head.removeChild(script);
            clearTimeout(script.timer);
            window[callbackName] = null;
            params.success && params.success(json);
        };
        script.src = params.url + '?' + data; // Start to request data from the background when setting src
        if (params.time) { // Limited time
            script.timer = setTimeout(function () {
                window[callbackName] = null;
                head.removeChild(script);
                params.error && params.error({
                    message: 'overtime'
                })
            }, params.time)
        }

    }
    function formatParams(data) {
        // Using encodeuriccomponent to encode a part of the URI
        var arr = [];
        for (var key in data) {
            arr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
        }
        // Add random numbers to prevent caching
        arr.push('v=' + random());
        return arr.join('&');
    }
    function random() {
        return Math.floor(Math.random() * 10000 + 500);
    }
    function setHeaders(xhr, headers) {
        for (var key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }
    }
}

Usage method

  • No JSON request

         Ajax({
        url: 'Back-end interface',
        type: 'POST',
        headers: {
          'Content-Type': 'application/json',
          token: 'xxx'
        },
        success(res) {
            console.log(res);
        },
        error(status) {
            console.log(`some error status = ${status}`);
        }
    })
  • jsonp request

      Ajax({
        url: 'http://localhost:8080',
        headers: {
          'Content-Type': 'application/json'
        },
        jsonp: 'getUser',
        time: 2000,
        success(res) {
            console.log(res);
        },
        error(status) {
            console.log(`some error status = ${status.msg}`);
        }
    })

JSON background configuration code

var querystring = require('querystring');
var http = require('http');
var server = http.createServer();

server.on('request', function(req, res) {
    var params = querystring.parse(req.url.split('?')[1]);
    var fn = params.callback;

    // JSON return settings
    res.writeHead(200, { 'Content-Type': 'text/javascript' });
    var data = {
        user: 'xbc',
        password: '123456'
    }
    res.write(fn + '(' + JSON.stringify(data) + ')');

    res.end();
});

server.listen('8080');
console.log('Server is running at port 8080...');

Reference articles

Topics: Javascript JSON xml