接上篇。引入了一个私有函数_serialize,它会把js对象串行化成HTTP所需参数模式,接受如下两种结构
1 | {name: 'jack' ,age:20} --> name=jack&age=20 |
2 | {fruit:[ 'apple' , 'banana' , 'orange' ]} --> fruit=apple&fruit=banana&fruit=orange |
请求后台的一个servlet,发送参数name=jack,age=20,默认使用异步,GET方式。现在data可以如下了
01 | Ajax.request( 'servlet/ServletJSON' ,{ |
02 | data : {name: 'jack' ,age:20}, |
03 | success : function (xhr){ |
04 | //to do with xhr |
05 | }, |
06 | failure : function (xhr){ |
07 | //to do with xhr |
08 | } |
09 | } |
10 | ); |
完整代码
01 | Ajax = |
02 | function (){ |
03 | function request(url,opt){ |
04 | function fn(){} |
05 | var async = opt.async !== false , |
06 | method = opt.method || 'GET' , |
07 | encode = opt.encode || 'UTF-8' , |
08 | data = opt.data || null , |
09 | success = opt.success || fn, |
10 | failure = opt.failure || fn; |
11 | method = method.toUpperCase(); |
12 | if (data && typeof data == 'object' ){ //对象转换成字符串键值对 |
13 | data = _serialize(data); |
14 | } |
15 | if (method == 'GET' && data){ |
16 | url += (url.indexOf( '?' ) == -1 ? '?' : '&' ) + data; |
17 | data = null ; |
18 | } |
20 | xhr.onreadystatechange = function (){ |
21 | _onStateChange(xhr,success,failure); |
22 | }; |
23 | xhr.open(method,url,async); |
24 | if (method == 'POST' ){ |
25 | xhr.setRequestHeader( 'Content-type' , 'application/x-www-form-urlencoded;charset=' + encode); |
26 | } |
27 | xhr.send(data); |
28 | return xhr; |
29 | } |
30 | function _serialize(obj){ |
31 | var a = []; |
32 | for ( var k in obj){ |
33 | var val = obj[k]; |
34 | if (val.constructor == Array){ |
35 | for ( var i=0,len=val.length;i<len;i++){ |
36 | a.push(k + '=' + encodeURIComponent(val[i])); |
37 | } |
38 | } else { |
39 | a.push(k + '=' + encodeURIComponent(val)); |
40 | } |
41 | } |
42 | return a.join( '&' ); |
43 | } |
44 | function _onStateChange(xhr,success,failure){ |
45 | if (xhr.readyState == 4){ |
46 | var s = xhr.status; |
47 | if (s>= 200 && s < 300){ |
48 | success(xhr); |
49 | } else { |
50 | failure(xhr); |
51 | } |
52 | } else {} |
53 | } |
54 | return {request:request}; |
55 | }(); |
这里仅仅是使data可以是对象类型,貌似没啥大用。但如果与表单(form)结合的话还是很有用的。当我们使用form但又想用Ajax方式提交,那么把form中元素序列化成HTTP请求的参数类型是一个费劲的活。这里写个工具函数formToHash,将form元素按键值形式转换成对象返回
01 | function formToHash(form){ |
02 | var hash = {}, el; |
03 | for ( var i = 0,len = form.elements.length;i < len;i++){ |
04 | el = form.elements[i]; |
05 | if (el.name == "" || el.disabled) continue ; |
06 | switch (el.tagName.toLowerCase()){ |
07 | case "fieldset" : |
08 | break ; |
09 | case "input" : |
10 | switch (el.type.toLowerCase()){ |
11 | case "radio" : |
12 | if (el.checked) |
13 | hash[el.name] = el.value; |
14 | break ; |
15 | case "checkbox" : |
16 | if (el.checked){ |
17 | if (!hash[el.name]){ |
18 | hash[el.name] = [el.value]; |
19 | } else { |
20 | hash[el.name].push(el.value); |
21 | } |
22 | } |
23 | break ; |
24 | case "button" : |
25 | break ; |
26 | case "image" : |
27 | break ; |
28 | default : |
29 | hash[el.name] = el.value; |
30 | break ; |
31 | } |
32 | break ; |
33 | case "select" : |
34 | if (el.multiple){ |
35 | for ( var j = 0, lens = el.options.length;j < lens; j++){ |
36 | if (el.options[j].selected){ |
37 | if (!hash[el.name]){ |
38 | hash[el.name] = [el.options[j].value]; |
39 | } else { |
40 | hash[el.name].push(el.options[j].value); |
41 | } |
42 | } |
43 | } |
44 | } else { |
45 | hash[el.name] = el.value; |
46 | } |
47 | break ; |
48 | default : |
49 | hash[el.name] = el.value; |
50 | break ; |
51 | } |
52 | } |
53 | form = el = null ; |
54 | return hash; |
55 | } |
新闻热点
疑难解答