关于JavaScript的AJAX
Mar 23, 2016
AJAX即“Asynchronous Javascript And XML”!它类似于DHTML或LAMP,AJAX不是指一种单一的技术,而是有机地利用了一系列相关的技术。
概念及特征
- AJAX在本质上是一个浏览器端的技术(依赖于window的相关函数对象),所以它也有很多浏览器的兼容性问题
- AJAX是用来描述基于用脚本操纵HTTP请求的Web应用架构。用脚本操纵HTTP和web服务器进行数据交换,但不会导致页面重载。
相似产物Comet
- Comet也是使用脚本操纵HTTP的Web应用架构的相关术语。
- Comet是Web服务器发起通信并异步发送消息到客户端的技术。(服务端向客户端“推送”数据)
- 而AJAX是客户端从服务端“拉取”数据
- Comet和Ajax都是美国的洗涤日用品牌!!!
- Comet GitHub外链: https://github.com/wandenberg/nginx-push-stream-module
底层实现 or “传输协议”
- “img”元素可以通过为其src属性设置特定URL,浏览器发起的HTTP GET请求会从这个URL上下载图片。虽然可以通过实例化HTMLImageElement对象即: new Image()的方式创建一个”img”,并为其src属性设置带有查询字符串信息的URL,实现客户端发送数据到服务器,但在客户端却无法轻易的从服务器 响应的图片中提取出信息!所以此技术常用于前端log记录!(这种类型的图片也称之为“网页信标”)
var unique = (function () {
//此方法也可用Math.random()代替
var time = (new Date()).getTime() + "-",
i = 1;
return function () {
return time + (i++);
}
})();
var imgLog = function (url) {
if (typeof url !== "string" || !url) {
return;
}
var uid = unique();
var img_id = "_img_" + uid;
var img = new Image();
img.hidden = true;
window[img_id] = img;
img.onload = img.onerror = function () {//销毁一些对象
img.onload = img.onerror = null;
img = undefined;
delete window[img_id];
}
url += url.indexOf("?") == "-1" ? '?_uid=' + uid : '&_uid=' + uid;
img.src = url;
};
- “iframe”则相比“img”元素强大些,也能通过设置它的src属性从服务端获取HTML文档。可以直接显示给用户,也可隐藏起来通过使用脚本遍历获取 相关数据!但其受制于“同源策略”。
- “script”元素也能通过设置它的src属性发起携带查询字符串参数的HTTP GET请求,且并不受制于“同源策略”!通常服务器会使用JSON格式将数据 返回给客户端,JavaScript解析器能自动将其“解码”(ps:返回一段以前端与服务器约定好命名的函数调用代码,服务端将前端需要的数据作为参数传入函数调用),此种AJAX传输协议也叫做“JSONP”。
function success(json) {
// 成功回调
}
// 创建 script 标签并加入到页面中
var callbackName = ('jsonp_' + Math.random()).replace(".", "");
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
head.appendChild(script);
var timer = setTimeout(function() {
window[callbackName] = undefined;
// 如果20s后还未能执行jsonp回调,则认为失败!...
// 如需要此处可增加异常逻辑处理,errorCallback()
}, 20000);
// 创建jsonp回调函数
// response为jsonp_随机数({JSON数据})
window[callbackName] = function (json) {
window.clearTimeout(timer);
head.removeChild(script);
window[callbackName] = undefined;
// 执行成功方法
success(json);
};
//发送请求(callback是和服务端约定的获取回调函数名称的key,而“callback”为大多数情况下的默认值)
script.src = "" + "?callback=" + callbackName;
- “XMLHttpRequest”更简单的异步交互技术!它定义了用脚本操作HTTP的API,并且所有的浏览器都支持XMLHttpRequest对象。虽然名字中含有XML 但它并没有限定只能使用XML文档,它能获取到任何类型的文本文档!
function createXHR(){
if(typeof XMLHttpRequest != "undefined"){ // 非IE6浏览器
return new XMLHttpRequest();
}else if(typeof ActiveXObject != "undefined"){ // IE6浏览器
var version = [
"MSXML2.XMLHttp.6.0",
"MSXML2.XMLHttp.3.0",
"Microsoft.XMLHTTP",
];
for(var i = 0; i < version.length; i++){
try{
return new ActiveXObject(version[i]);
}catch(e){
//异常处理
}
}
}else{
throw new Error("您的系统或浏览器不支持XHR对象!");
}
}
// 封装ajax
function createAjax(obj){
obj = obj || {};
var xhr = createXHR();
obj.url = obj.url + "?rand=" + Math.random(); // 防止缓存
if(obj.method === "get"){ // 判断使用的是否是get方式发送
obj.url += obj.url.indexOf("?") == "-1" ? "?" + obj.data : "&" + obj.data;
}
// 异步的时候需要触发onreadystatechange事件,同步的省略...
xhr.onreadystatechange = function(){
// 执行完成
if(xhr.readyState === 4){
callBack();
}
}
//open方法的3个参数(HTTP方法或动作, URL, 是否异步)
xhr.open(obj.method, obj.url, true);
//设置http头,但大多数的http头信息是无法改变的!
//application/x-www-form-urlencoded 数据被编码为名称/值对 最常见的格式
//multipart/form-data 使用表单上传文件时使用
//application/json 用来告诉服务端消息主体是序列化后的 JSON 字符串
//text/xml 使用XML作为编码方式的远程调用
//text/plain 以纯文本形式进行编码
if (obj.method === "post") {
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(obj.data);
} else {
xhr.send(null);
}
//返回数据
//同步时,直接调用
function callBack() {
// 判断是否返回正确
if (xhr.status === 200) {
if (typeof obj.success === "function") {
obj.success(xhr.response);
}
} else {
if (typeof obj.error === "function") {
obj.error(xhr.response);
}
}
//xhr.status === 0请求失败
//xhr.statusText === "abort" 请求被cancle
//xhr.statusText === "timeout" 请求超时
}
}
createAjax({
"method" : "get",
"url" : "目的URI",
"data" : '',
"success" : function(data){
//成功处理动作
},
"error" : function(data){
//失败处理动作
}
});