31-1同步与异步请求、混编、AJAX、原生AJAX封装

262 阅读3分钟

1、在1999年之前所有的网页都是服务端(php、python、jsp...)渲染的,就是页面如果需要动态数据的时候,通过页面跳转的方式传参数,给服务端。服务端把数据从数据库里面获取出来,渲染到html文档里面,然后再给客户端返回新的html文档,浏览器再重新解析html文档,最后渲染。这个也叫混编,这个页面的渲染都是同步的方式加载,服务端的代码是不会返回到前端的,服务端只会返回处理后的结果,也就是html文档。

同步加载出现一个问题,每一次获取新的数据都导致整个文档页面被替换,页面重流,解析、渲染。在这之前也就没有前后端分离

2、1999年微软IE为了解决页面重流的问题。发明了异步加载AJAX(Asynchronous Javascript and XML 异步的javascrit和xml), 允许js脚本单独向服务器发起http请求的功能。服务端返回xml文档,由js脚本解析。

3、2005年AJAX被大厂公认命名

4、2006年W3C发布AJAX的国际标准。

总结什么是Ajax:javascript发起http通信。

XMLHttpRequest的版本:

XMLHttpRequest的版本分为:Leave 1和Leave2

leave1:的缺点:

1、无法发送跨域的请求;

2、不能获取非纯文本的数据;

3、无法获取传输进度条;

4、无法设置请求超时时间;

leave2的改进:

1、可以跨域请求

2、支持获取二进制的数据;

3、支持文件上传

4、formdata对象

5、可以获取传输进度条

6、可以设置超时时间

leave2的兼容问题: 1、IE8/9、Opara Min不支持xhr对象 2、IE10/11 不支持响应类型为json的数据 3、部分浏览器不支持超市设置 4、部分浏览器不支持blob(文件对象的二进制数据)

leave2 AJAX 的5个事件(可能会存在兼容性的问题):

1、onloadstart:绑定http请求发出的监听函数;

2、 onerror:绑定请求失败的监听函数;

3、 onload:绑定请求成功完成的监听函数;

4、 onabort:绑定请求终止的监听函数(调用了abort方法)

5、 onloadend:绑定请求完成(不管成功与否都触发)的监听函数

触发顺序:loadStart->readState===4->load/error/abort->loadend

xhr对象的状态readystate

  • 0: UNSENT

    XMLHttpRequest 代理已被创建, 但尚未调用 open() 方法。

  • 1: OPENED

    open() 方法已经被触发。在这个状态中,可以通过  setRequestHeader()方法来设置请求的头部, 可以调用 send() 方法来发起请求。

  • 2: HEADERS_RECEIVED

send() 方法已经被调用,响应头也已经被接收。

  • 3: LOADING

响应体部分正在被接收。如果 responseType 属性是“text”或空字符串, responseText 将会在载入的过程中拥有部分响应数据。

  • 4: DONE

请求操作已经完成。这意味着数据传输已经彻底完成或失败。

ajax封装:

var $ = (function() {
	function initXHR() {
		var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
		if (!xhr) {
			throw new Error('你的浏览器不支持异步请求')
		}
		return xhr;
	}
	function doAjax(opt) {
		var xhr = initXHR(),
			opt = opt || {},
			type = (opt.type || 'GET').toUpperCase(),
			url = opt.url,
			formart = opt.formart,
			data,
			timer,
			timeout = opt.timeout || 6000,
			error = opt.error || function() {},
			success = opt.success || function() {},
			complete = opt.complete || function() {},
			// 设置异步和同步,默认为异步true
			async = opt.async + '' === 'false' ? false : true;
		timer = setTimeout(function() {
			console.log('取消请求');
			clearTimeout(timer);
			timer = null;
			xhr.abort();
			xhr = null;
			complete()
		}, timeout);
		xhr.open(type, url, async);
		xhr.onreadystatechange = function() {
			if (xhr.readyState === 4) {
				if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
					success(JSON.parse(xhr.responseText));
				} else {
					error();
				}
				clearTimeout(timer);
				timer = null;
				xhr = null;
				complete();
			}
		}
		data = opt.data ? dateFormart(opt.data, xhr, formart) : null;
		xhr.send(type === 'GET' ? null : data)
	}
	function dateFormart(data, xhr, formart) {
		if (formart === 'form') {
			var str = ''
			xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencode');
			for (let key in data) {
				str += key + '=' + data[key] + '&'
			}
			return str.slice(0, -1)
		}
		xhr.setRequestHeader('Content-Type', 'application/json');
		return JSON.stringify(data)
	}
	return {
		ajax: function(opt) {
			doAjax(opt);
		},
		post: function(url, data, formart, success, error, complete) {
			doAjax({
				url: url,
				data: data,
				type: 'post',
				formart: formart,
				success: success,
				error: error,
				complete: complete
			})
		},
		get: function(url, success, error, complete) {
			doAjax({
				url: url,
				type: 'get',
				success: success,
				error: error,
				complete: complete
			})
		}
	}
}());