Skip to content

Instantly share code, notes, and snippets.

@monjer
Last active December 15, 2015 02:29
Show Gist options
  • Select an option

  • Save monjer/5187774 to your computer and use it in GitHub Desktop.

Select an option

Save monjer/5187774 to your computer and use it in GitHub Desktop.
Ajax封装类
(function(opt_ns , opt_wind){
var g_win = opt_wind || top ;
var g_doc = g_win.document ;
var ajax = {
fireEvent : function(xhr , type , handlers , timerId){
var handler = handlers["on"+type];
if(timerId){
clearTimeout(timerId);
}
if(handler && typeof handler == "function"){
if(type=="success"){
handler(xhr, xhr.responseText);
}else{
handler(xhr);
}
}
},
/**
* 获取XMLHttpRequest对象
* @return {XMLHttpRequest} XMLHttpRequest对象
*/
getXHR : function(){
if(g_win.XMLHttpRequest){
return new XMLHttpRequest();
}else{
if(g_win.ActiveXObject){
try {
return new ActiveXObject("MSXML2.XMLHTTP.3.0");
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
}
},
XHR_STATE : {
/*open()has not been called yet.*/
"UNSENT":0,
/*open() has called successfully , but send()has not been called . During this state request headers can be set using setRequestHeader()*/
"OPENED":1,
/*send() has been called, and respnse headers and status are available.*/
"HEADERS_RECEIVED":2 ,
/*Downloading; responseText holds partial data.the response entity body is being received*/
"LOADING":3 ,
/* The operation is complete.data transfer has completed or something wrong has happend during transfer*/
"DONE":4
},
blank : function(){},
/**
* @purpose 发送ajax请求
* @param {Object} url 链接地址
* @param {Object} opt_options 配置选项
* @return {XMLHttpRequest} xhr
* @options {String} method[GET] 请求类型
* @options {String} data 请求发送的参数,注意用URL编码转码
* @options {Boolean} asyn[true] 是否为异步请求
* @options {String} username[""] 用户名
* @options {String} password[""] 密码
* @options {Number} timerId[0] 超时时间(ms)
* @options {Boolean} cache[false] 请求是否被缓存,1.1.1起支持
* @options {Object} headers http请求头设置hash对象
* @options {Function} onsuccess 请求成功回调 function(XMLHttpRequest xhr, string responseText)。
* @options {Function} onfaliure 请求成功回调 function(XMLHttpRequest xhr)。
* @options {Function} onbeforerequest 发送请求前调用 function(XMLHttpRequest xhr)
* @options {Function} ontimeout 超时回调 function(XMLHttpRequest xhr)
* @options {Function} onstate 返回状态回调 function(XMLHttpRequest xhr)
*/
request : function(url , opt_options){
if(typeof url === "object"){
opt_options = url ;
url = opt_options.url ;
}
// 可选项初始化
var options = opt_options || {} ,
method = (options.method || "GET").toUpperCase(),
data = options.data || {},
asyn = options.asyn || true ,
username = options.username || "" ,
passoword = options.password || "" ,
timeout = options.timeout || 0 ,
timerId = 0 ,
cache = options.cache || false ,
headers = options.headers || {} ;
//onsuccess,onfaliure,onbeforerequest,state,ontimeout
eventHandlers = {};
//获取eventHandlers
for(var key in options){
if(options.hasOwnProperty(key)){
eventHandlers[key] = options[key];
}
}
try {
var xhr = ajax.getXHR();
//内部函数作为闭包,可以拥有外部作用域的所有变量,简化对this的使用
function readyStateChangeHandler(){
if(xhr.readyState == ajax.XHR_STATE["DONE"]){
try{
var status = xhr.status ;
/*From GWT XMLHTTPRequest.java http://code.google.com/p/google-web-toolkit/
try {
if (xhr.status === undefined) {
return "xhr.status == undefined, please see Safari bug " +
"http://bugs.webkit.org/show_bug.cgi?id=3810 for more details";
}
return null;
}catch (e) {
return "Unable to read xhr.status; likely causes are a " +
"networking error or bad cross-domain request. Please see " +
"https://bugzilla.mozilla.org/show_bug.cgi?id=238559 for more " +
"details";
}*/
}catch(e){
//failure
ajax.fireEvent(xhr , "failure" , eventHandlers , timerId);
return ;
}
if((status >= 200 && status < 300) || status == 304 || status == 1223 ){
//success
ajax.fireEvent(xhr , "success" , eventHandlers , timerId);
}else{
//failure
ajax.fireEvent(xhr , "failure" , eventHandlers , timerId);
}
/*
* NOTE: Testing discovered that for some bizarre reason, on Mozilla, the
* JavaScript <code>XmlHttpRequest.onreadystatechange</code> handler
* function maybe still be called after it is deleted. The theory is that the
* callback is cached somewhere. Setting it to null or an empty function does
* seem to work properly, though.
*
* On IE, there are two problems: Setting onreadystatechange to null (as
* opposed to an empty function) sometimes throws an exception. With
* particular (rare) versions of jscript.dll, setting onreadystatechange from
* within onreadystatechange causes a crash. Setting it from within a timeout
* fixes this bug (see issue 1610).
*
* End result: *always* set onreadystatechange to an empty function (never to
* null). Never set onreadystatechange from within onreadystatechange (always
* in a setTimeout()).
*/
g_win.setTimeout(function(){
//此处不包含循环引用,blank函数不在包含xhr的作用域内
xhr.onreadystatechange = ajax.blank;
} , 0);
}
}
if(method == "GET"){
/**
* 对于GET中传入的data,不保证已被转码,传入的数据必须是转码后的结果
*/
if(data){
url += (url.indexOf("?") >=0 ? "&" : "?")+data
}
/**
* HTTP GET
*
* 只要满足缓存条件,响应可以被缓存
*
* HTTP POST
*
* 响应不可被缓存,但服务器可以在响应中指定合适的Cache-Control 或 Expires header fields
*
*/
if(!cache){
url += (url.indexOf("?") >= 0 ? "&" : "?")+"t="+new Date().getTime();
}
}
if(username){
xhr.open(method , url , asyn , username , password);
}else{
xhr.open(method , url , asyn);
}
if(asyn){
xhr.onreadystatechange = readyStateChangeHandler ;
}
//setRequestHeader 必须在open之后,send之前调用.
if(method == "POST"){
//以Form格式提交POST数据,否则后台服务端无法处理请求
xhr.setRequestHeader('Content-Type', headers["Content-Type"]||'application/x-www-form-urlencoded');
}
//在HTTP协议中表明此请求来自Ajax,在后台可以根据此报文头对Ajax过滤
// http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
headers["X-Requested-With"] = "XMLHttpRequest";
for(var key in headers){
if(headers.hasOwnProperty(key)){
xhr.setRequestHeader(key , headers[key]);
}
}
//beforerequest
ajax.fireEvent(xhr , "beforerequest" , eventHandlers , timerId);
if(timeout){
timerId = setTimeout(function(){
xhr.onreadystatechange = ajax.blank ;
xhr.abort();
//timeout
ajax.fireEvent(xhr , "timeout" , eventHandlers , timerId);
} , timeout);
}
//data在传送前应该利用encodeURIComponent转码
//http://www.w3.org/TR/html401/interact/forms.html#form-content-type
xhr.send(data);
// 同步调用
if(!asyn){
readyStateChangeHandler();
}
}catch (e) {
//failure
ajax.fireEvent(xhr , "failure" , eventHandlers , timerId);
}
},
/**
* @purpose 发送一个post请求
* @param {Object} url 地址
* @param {Object} opt_options 参数对象
*/
post:function(url , opt_options){
var options = opt_options || {};
opt_options.method = "post";
return ajax.request(url , opt_options);
},
/**
* @purpose 发送一个get请求
* @param {Object} url 地址
* @param {Object} opt_options 参数对象
*/
get:function(url , opt_options){
var options = opt_options || {};
opt_options.method = "get";
return ajax.request(url , opt_options);
}
};
g_win.ajax = ajax ;
}(undefined , window))
@monjer

monjer commented Nov 9, 2013

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment