1+ /**
2+ * Created by zhufengpeixun on 2016/10/29.
3+ */
4+ //{
5+ // url: '',ajax请求地址
6+ // method: 'get',http方法
7+ // headers: {},自定义请求首部
8+ // async: true,是否为异步请求
9+ // data: {},往服务器发送的参数
10+ // success: function () { 成功时执行的回调函数
11+ // },
12+ // error: function () { 失败时执行的回调函数
13+ // },
14+ // cache: false 是否缓存
15+ // dataType:'json' 格式化服务器返回的数据类型
16+ //}
17+ ( function ( ) {
18+ /**
19+ * ajax核心逻辑
20+ * @param {Object } options 用户配置参数
21+ */
22+ function ajax ( options ) {
23+ // 判断参数是否为一个对象
24+ if ( ! tools . isType ( options , 'Object' ) ) {
25+ throw new TypeError ( '参数类型错误' ) ;
26+ }
27+ // 获取ajax对象
28+ var xhr = tools . getXHR ( ) ;
29+
30+ // 设置http方法默认值
31+ options . method || ( options . method = 'get' ) ;
32+ options . url || ( options . url = '/' ) ;
33+ // 因为undefined在低版本ie存在一个bug,可以被重写的bug
34+ // 所以这里不直接判断是否等于undefined 而是判断void表达式
35+ options . async === void 0 || ( options . async = true ) ;
36+
37+ var url = options . url ;
38+ // 将data格式化为querystring格式
39+ var data = tools . param ( options . data ) ;
40+
41+ // 将querystring格式的data拼接到url后面
42+ // 1、get系方法 将data格式化为querystring拼接到url后
43+ // 如果是get系 则将data设置为空
44+ if ( / ^ g e t | d e l e t e | h e a d $ / ig. test ( options . method ) && data ) {
45+ url = tools . appendToURL ( url , data ) ;
46+ data = null ;
47+ }
48+
49+ // 2、如果cache为false 需要往url后面添加随机数
50+ if ( options . cache === false ) {
51+ var ran = ( Math . random ( ) ) . toString ( 36 ) . slice ( 2 ) ;
52+ url = tools . appendToURL ( url , '_=' + ran ) ;
53+ }
54+
55+
56+ // 执行open方法
57+ xhr . open ( options . method , url , options . async ) ;
58+
59+ // 设置自定义请求首部
60+ if ( xhr . setRequestHeader && options . headers ) {
61+ for ( var header in options . headers ) {
62+ if ( ! options . headers . hasOwnProperty ( header ) ) {
63+ continue ;
64+ }
65+ xhr . setRequestHeader ( header , options . headers [ header ] ) ;
66+ }
67+ }
68+
69+ // step 3 接收服务器响应
70+ xhr . onreadystatechange = function ( ) {
71+ // 判断http事务是否完成
72+ if ( xhr . readyState === 4 ) {
73+ // 获取http响应主体
74+ var response = xhr . responseText ;
75+ // 判断状态码是否成功
76+ if ( / ^ 2 \d { 2 } $ / . test ( xhr . status ) || xhr . status === 304 ) {
77+ // 判断是否需要将响应主体格式化json对象
78+ if ( options . dataType === 'json' ) {
79+ // 因为response不是合法的json字符串的话,执行JSONParse会报错。所以这里用try catch包住
80+ try {
81+ response = tools . JSONParse ( response ) ;
82+ } catch ( ex ) {
83+ options . error && options . error ( ex ) ;
84+ return ;
85+ }
86+ }
87+ options . success && options . success ( response ) ;
88+
89+ } else if ( / ^ ( 4 | 5 ) \d { 2 } $ / . test ( xhr . status ) ) {
90+ options . error && options . error ( new Error ( '服务器出错' ) ) ;
91+ }
92+ }
93+ } ;
94+
95+ // step 4 发送请求
96+ xhr . send ( data ) ;
97+ }
98+
99+ var tools = {
100+ /**
101+ * 判断视距类型
102+ * @param {* } data 需要判断类型的数据
103+ * @param {string } type 数据格式
104+ * @return {boolean } 数据格式是否匹配
105+ */
106+ isType : function ( data , type ) {
107+ return Object . prototype . toString . call ( data ) === '[object ' + type + ']' ;
108+ } ,
109+ /**
110+ * 利用惰性函数获取ajax对象
111+ */
112+ getXHR : ( function ( ) {
113+ var XHRList = [ function ( ) {
114+ return new XMLHttpRequest ( ) ;
115+ } , function ( ) {
116+ return new ActiveXObject ( 'Microsoft.XMLHTTP' ) ;
117+ } , function ( ) {
118+ return new ActiveXObject ( 'Msxml2.XMLHTTP' ) ;
119+ } , function ( ) {
120+ return new ActiveXObject ( 'Msxml3.XMLHTTP' ) ;
121+ } ] ;
122+
123+ var xhr = null ;
124+ while ( xhr = XHRList . shift ( ) ) {
125+ try {
126+ xhr ( ) ;
127+ return xhr ;
128+ } catch ( ex ) {
129+
130+ }
131+ }
132+ throw new ReferenceError ( '当前浏览器不支持ajax功能' ) ;
133+ } ) ( ) ,
134+ /**
135+ * 将对象格式化为querystring格式
136+ * @see {a:1,b:2} => a=1&b=2
137+ * @param data
138+ */
139+ param : function ( data ) {
140+ // 因为该方法的目的就是返回一个字符串,参数已经是一个字符串则直接返回
141+ if ( typeof data === 'string' ) {
142+ return data ;
143+ }
144+ // 如果参数为null或者undefined 返回空字符串
145+ if ( data === null || data === void 0 ) {
146+ return '' ;
147+ }
148+ // 如果data是一个对象
149+ if ( tools . isType ( data , 'Object' ) ) {
150+ var arr = [ ] ;
151+ for ( var key in data ) {
152+ if ( ! data . hasOwnProperty ( key ) ) continue ;
153+ // 因为url中不能存在非英文字符
154+ arr . push ( encodeURIComponent ( key ) + '=' + encodeURIComponent ( data [ key ] ) ) ;
155+ }
156+ return arr . join ( '&' ) ;
157+ }
158+
159+ // 参数既不是string 也不是对象、null、undefined 则直接toString返回
160+ return data . toString ( ) ;
161+ } ,
162+ /**
163+ * 往url后面拼接字符串
164+ */
165+ appendToURL : function ( url , str ) {
166+ // 先调用param方法,格式化下str
167+ str = this . param ( str ) ;
168+ if ( ! str ) {
169+ return url ;
170+ }
171+ // 判断url中是否存在问号
172+ var hasQuery = / \? / . test ( url ) ;
173+ return url + ( hasQuery ? '&' : '?' ) + str ;
174+ } ,
175+ /**
176+ * 将json字符串格式化为json对象
177+ * @param {string } JSONString json字符串
178+ * @return {Object } 转化后的json对象
179+ */
180+ JSONParse : function ( JSONString ) {
181+ if ( window . JSON ) {
182+ return JSON . parse ( JSONString )
183+ }
184+ return eval ( '(' + JSONString + ')' ) ;
185+ }
186+ } ;
187+
188+ this . ajax = ajax ;
189+ } ( ) ) ;
0 commit comments