接上篇。引入了一个私有函数_serialize,它会把js对象串行化成HTTP所需参数模式,接受如下两种结构
{name:'jack',age:20} --> name=jack&age=20 {fruit:['apple','banana','orange']} --> fruit=apple&fruit=banana&fruit=orange
请求后台的一个servlet,发送参数name=jack,age=20,默认使用异步,GET方式。现在data可以如下了
Ajax.request('servlet/ServletJSON',{ data : {name:'jack',age:20}, success : function(xhr){ //to do with xhr }, failure : function(xhr){ //to do with xhr } } );
完整代码
Ajax = function(){ function request(url,opt){ function fn(){} var async = opt.async !== false, method = opt.method || 'GET', encode = opt.encode || 'UTF-8', data = opt.data || null, success = opt.success || fn, failure = opt.failure || fn; method = method.toUpperCase(); if(data && typeof data == 'object'){//对象转换成字符串键值对 data = _serialize(data); } if(method == 'GET' && data){ url += (url.indexOf('?') == -1 ? '?' : '&') + data; data = null; } var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); xhr.onreadystatechange = function(){ _onStateChange(xhr,success,failure); }; xhr.open(method,url,async); if(method == 'POST'){ xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=' + encode); } xhr.send(data); return xhr; } function _serialize(obj){ var a = []; for(var k in obj){ var val = obj[k]; if(val.constructor == Array){ for(var i=0,len=val.length;i<len;i++){ a.push(k + '=' + encodeURIComponent(val[i])); } }else{ a.push(k + '=' + encodeURIComponent(val)); } } return a.join('&'); } function _onStateChange(xhr,success,failure){ if(xhr.readyState == 4){ var s = xhr.status; if(s>= 200 && s < 300){ success(xhr); }else{ failure(xhr); } }else{} } return {request:request}; }();
这里仅仅是使data可以是对象类型,貌似没啥大用。但如果与表单(form)结合的话还是很有用的。当我们使用form但又想用Ajax方式提交,那么把form中元素序列化成HTTP请求的参数类型是一个费劲的活。这里写个工具函数formToHash,将form元素按键值形式转换成对象返回
function formToHash(form){ var hash = {}, el; for(var i = 0,len = form.elements.length;i < len;i++){ el = form.elements[i]; if(el.name == "" || el.disabled) continue; switch(el.tagName.toLowerCase()){ case "fieldset": break; case "input": switch(el.type.toLowerCase()){ case "radio": if(el.checked) hash[el.name] = el.value; break; case "checkbox": if(el.checked){ if(!hash[el.name]){ hash[el.name] = [el.value]; }else{ hash[el.name].push(el.value); } } break; case "button": break; case "image": break; default: hash[el.name] = el.value; break; } break; case "select": if(el.multiple){ for(var j = 0, lens = el.options.length;j < lens; j++){ if(el.options[j].selected){ if(!hash[el.name]){ hash[el.name] = [el.options[j].value]; }else{ hash[el.name].push(el.options[j].value); } } } }else{ hash[el.name] = el.value; } break; default: hash[el.name] = el.value; break; } } form = el = null; return hash; }
相关: