欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-09 14:55:49
...

首先,我很清楚 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);
};