19

今天手动编写了一个简易的 ajax 发起器(JavaScript)-Shane from Spads

 4 years ago
source link: https://blog.51cto.com/shanelooli/2421287
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

今天手动编写了一个简易的 ajax 发起器(JavaScript)

首先,我很清楚 jQuery , zepto 等框架的包装并没有问题。所以虽然我做得还挺符合 jQuery 规范的,但其实我做得这个事情并没有实际上的生产意义,只能用于令人更了解实现侧的过程,同时对我个人而言算是一种娱乐……
对于我做得项目,只有很轻小以致于整个项目代码也到不了 jquery-min.js 文件大小的情况,才会使用我自写的这个发起器,并且不会用源码版,会用压缩版。另外我觉得做一个前后端连用的框架,所有请求都通过 jsonp 的方式,也许反倒可以简洁一些。

var _shaneAjaxRef = { };
/**
 * @author  Shane Loo Li
 * @version 1.1.0, 2019-7-18 Thursday
 * @param   configObj   { }
 * url
 * type
 * data
 * async
 * dataType xml, html, script, text will return text itself. json wil return object. jsonp will run return text as JavaScript.
 * success  function
 * error    function
 * complete function
 */
var shaneAjax = function(configObj)
{
    if (!configObj || !configObj.url) { return; }
    try
    {
        if (configObj.dataType && configObj.dataType == 'jsonp')
        {
            _shaneAjaxRef.goJsonp(configObj);
        }
        else
        {
            _shaneAjaxRef.goRealAjax(configObj);
        }
    }
    catch (err)
    {
        if (configObj.error)
        {
            configObj.error(xmlhttp, '' + err, err);
        }
        if (configObj.complete)
        {
            configObj.complete(xmlhttp, 'error');
        }
    }
};
_shaneAjaxRef.buildNewXmlhttp = function()
{
    return window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
}
_shaneAjaxRef.buildDataStr = function(data)
{
    if (!data) return '';
    var result = '';
    for (var key in data)
    {
        if (data[key] instanceof Array)
        {
            var values = data[key];
            for (var i = -1; ++i != values.length; )
            {
                if (result) { result += '&'; }
                result += key + '=' + values[i];
            }
        }
        else
        {
            if (result) { result += '&'; }
            result += key + '=' + data[key];
        }
    }
    return result;
};
_shaneAjaxRef.goJsonp = function(configObj)
{
    var i = -1;
    while (++i != 65536 && window['jsonp' + i]) { }
    window['jsonp' + i] = function(responseDataObj)
    {
        if (configObj.success)
        {
            configObj.success(responseDataObj, 'success');
        }
        delete window['jsonp' + i];
    };

    var reqUrl = configObj.url;
    var dataStr = _shaneAjaxRef.buildDataStr(configObj.data);
    reqUrl += (reqUrl.indexOf('?') == -1 ? '?' : '&') + 'callback=jsonp' + i;
    if (dataStr)
    {
        reqUrl += '&' + dataStr;
    }

    var d_script = document.createElement('script');
    d_script.setAttribute('src', reqUrl);
    document.getElementsByTagName('head')[0].appendChild(d_script);
};
_shaneAjaxRef.goRealAjax = function(configObj)
{
    var xmlhttp = _shaneAjaxRef.buildNewXmlhttp();
    xmlhttp.onreadystatechange = function()
    {
        if (xmlhttp.readyState == 4)
        {
            var success = xmlhttp.status == 200;
            if (success)
            {
                if (configObj.success)
                {
                    var dataType = configObj.dataType ? configObj.dataType : 'json';
                    switch (dataType)
                    {
                        case 'xml':
                        case 'html':
                        case 'script':
                        case 'text':
                            configObj.success(xmlhttp.responseText, 'success');
                            break;
                        case 'json':
                            configObj.success(JSON.parse(xmlhttp.responseText), 'success');
                            break;
                        case 'jsonp':
                            configObj.success(eval(xmlhttp.responseText), 'success');
                    }
                }
            }
            else
            {
                if (configObj.error)
                {
                    configObj.error(xmlhttp, 'http status = ' + xmlhttp.status, null);
                }
            }
            if (configObj.complete)
            {
                configObj.complete(xmlhttp, success ? 'success' : 'error');
            }

        }
    };
    var reqMethod = configObj.type ? configObj.type : 'GET';
    var reqUrl = configObj.url;
    var dataStr = _shaneAjaxRef.buildDataStr(configObj.data);
    if (reqMethod == 'GET' && dataStr)
    {
        reqUrl += (reqUrl.indexOf('?') == -1 ? '?' : '&') + dataStr;
    }
    var reqAsync = configObj.async === false ? false : true;
    xmlhttp.open(reqMethod, reqUrl, reqAsync);
    if (reqMethod == 'POST' || reqMethod == 'PUT')
    {
        xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    }
    if ((reqMethod == 'POST' || reqMethod == 'PUT') && dataStr)
    {
        xmlhttp.send(dataStr);
    }
    else
    {
        xmlhttp.send();
    }
};

下面是一个测试程序。如果用 jsonp 就可以访问,否则不行。

var test = function()
{
    console.log(1);
    // https://www.baidu.com/s?wd=ajax&rsv_spt=1&rsv_iqid=0xf9544c340001dd09&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&oq=jQuery%2520ajax&inputT=1899&rsv_t=25bdncCkCLyr12l2gBax5GxF5yjzYUnHj2M%2FMv%2Fd1YsIlJpcW4%2BYljBcIhDw8f9CnkkY&rsv_pq=8e82b6400002164e&rsv_sug3=32&rsv_sug1=20&rsv_sug7=101&rsv_sug2=0&rsv_sug4=2655
    shaneAjax({
        type: 'GET',
        url: 'http://www.baidu.com/s',
        data: {
            wd: 'ajax',
            rsv_spt: 1,
            rsv_iqid: '0xf9544c340001dd09',
            issp: 1,
            f: 8,
            rsv_bp: 1,
            rsv_idx: 2,
            ie: 'utf-8',
            rqlang: 'cn',
            tn: 'baiduhome_pg',
            rsv_enter: 1,
            oq: 'jQuery%20ajax',
            inputT: 1899,
            rsv_t: '25bdncCkCLyr12l2gBax5GxF5yjzYUnHj2M/Mv/d1YsIlJpcW4+YljBcIhDw8f9CnkkY',
            rsv_pq: '8e82b6400002164e',
            rsv_sug3: 32,
            rsv_sug1: 20,
            rsv_sug7: 101,
            rsv_sug2: 0,
            rsv_sug4: 2655
        },
        dataType: 'jsonp',
        success: function(result)
        {
            console.log(result);
        },
        complete: function()
        {
            console.log('complete');
        }
    });
    console.log(2);
};

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK