ajax实现参考
function ajax(opt) {
//default _o
var _o = {
url: '/',
async: true, //是否异步
contentType: 0, //head编码方式,0 - urlencoded; 1 - json;2 - form-data
jsonForce: true, //是否强制要求返回格式为json
processData: true, //是否序列化参数
type: 'GET', //method
data: null,
before: function(xhr) {},
success: function(res, xhr) {},
error: function(res, xhr) {},
complete: function(res, xhr) {}
};
//extend opt
for (var pname in opt) {
if (pname === 'type') {
_o[pname] = opt[pname].toUpperCase();
} else {
_o[pname] = opt[pname];
}
}
//1.创建XMLHttpRequest实例
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
//是否需要将返回结果转换为json
var resTxt = _o.jsonForce ? JSON.parse(xhr.responseText || null) : xhr.responseText;
//do always callback
_o.complete(resTxt, xhr);
var stat = xhr.status;
if (stat < 200 || stat >= 300 && stat !== 304) { //do error callback
_o.error(resTxt, xhr);
} else { //do success callback
_o.success(resTxt, xhr);
}
}
};
//如果contentType不为0,强制不拼接
_o.contentType !== 0 && (_o.processData = false);
//拼接data
var _data = _o.data || null;
if (_data && _o.processData && typeof _data === "object") {
var _arrData = [];
for (var key in _data) {
_arrData.push(encodeURIComponent(key) + "=" + encodeURIComponent(_data[key]));
}
_data = _arrData.join('&').replace(/%20/g, '+');
if (_o.type === 'GET') { //get 拼接url
_o.url += (/\?/.test(_o.url) ? '&' : '?') + _data;
_data = null;
}
}
xhr.open(_o.type, _o.url, _o.async);
_o.before(xhr);
if (_o.type === 'POST') { //post 改头
if (_o.contentType === 0) {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
} else if (_o.contentType === 1) {
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
_data = JSON.stringify(_data);
}
}
xhr.send(_data);
}
XmlHttpRequest介绍
XHR英文全名XmlHttpRequest,中文可以解释为可扩展超文本传输请求。Xml可扩展标记语言,Http超文本传输协议,Request请求……XMLHttpRequest 对象是名为 AJAX 的 Web 应用程序架构的一项关键功能。
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
通信过程,总共分4步:
- 实例化XmlHttpRequest
var xhr = new XMLHttpRequest();
通常在实例化之前,要处理传入进来的配置参数,即“声明默认参数”和“自定义参数覆盖”。IE7+支持直接实例化,其他兼容请自行查找。
- 设置事件监听
此处是最核心的部分,也是最复杂的部分,在下一小节有较详细的说明。xhr.onreadystatechange = function() { switch (xhr.readyState) { case 1: //after open() before send() break; case 2: //after send() before receive break; case 3: //receiving not finish break; case 4: //all finish and close break; } };
- 建立连接
xhr.open(_o.type, _o.url, _o.async);
由于GET方式下,要将参数都拼接到URL上,所以在建立连接之前,通常都会先进行参数拼接。如果POST走的urlencoded模式的话,此处拼接的数据可以直接传。
另外,POST设置请求头(Content-Type),要在open之后,send之前执行,这点要注意!
- 发送数据
xhr.send(_data);
最后一步,发送数据就行了,GET方式下发送null。
关于readyState与onreadystatechange的说明
readyState变化会触发onreadystatechange监听,readyState一共有0~4五个值(0没有触发过,暂时还不清楚原因),说明如下:
readyState
|
说明
|
触发事件
|
备注
|
---|---|---|---|
0 | 请求未初始化 | ||
1 | 服务器连接已建立 | xhr.open() | 设置头(content-type)必须要在此之后 |
2 | 请求已接收 | xhr.send() | 此时可调用xhr.abort()主动结束请求,即利用定时器设置超时时间 |
3 | 请求处理中 | 开始接收信息,未接收完 | 此时无法访问xhr.responseText对象 |
4 | 请求已完成,且响应已就绪 | 信息接收完毕或主动关闭 | 业务逻辑代码主要就在这里了 |
参考资料:http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_onreadystatechange.asp
关于content-type的说明
METHOD | PARAMS | CONTENT-TYPE | 说明 | |
---|---|---|---|---|
GET | key1=val1&key2...... | 不需要设置 | 1.无需设置头 2.参数要加到url里,紧跟在?之后 3.xhr.send(null) | |
POST | key1=val1&key2...... | application/x-www-form-urlencoded; charset=UTF-8 |
| 1.需要设置头 2.与用form表单提交的模式是一样的 |
JSON.stringify(object) | application/json; charset=utf-8 |
| 1.需要设置头 2.数据结构可以很复杂 | |
new FormData() | 不需要设置 浏览器会自动识别,设置成 multipart/form-data; boundary=xxxxxx |
| 1.无需设置头,浏览器会自动识别是FormData类型 2.boundary的作用就是“华丽的分割线” 3.IE10+ |