论坛首页 入门技术论坛

改造请求参数---Ajax之二

浏览 3811 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-08-16   最后修改:2010-08-18

接上篇。引入了一个私有函数_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请求,返回XMLHttpRequest
 * Ajax.request(url,{
 * 		async 	是否异步 true(默认)
 * 		method 	请求方式 POST or GET(默认)
 * 		encode 	请求的编码 UTF-8(默认)
 * 		data 	请求参数 (键值对字符串或js对象)
 * 		success 请求成功后响应函数 参数为xhr
 * 		failure 请求失败后响应函数 参数为xhr
 * });
 *
 */
var 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元素按键值形式转换成对象返回。

 

/**
 * 把表单内容转换为hash对象
 * @param {HTMLElement} form对象
 * @return {hash}
 * @example
 *         formToHash(document.forms[0]);
 */
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;
}
 

好了,有了formToHash就可以将其返回的对象作为Ajax的参数data了,Ajax内部的_serialize能自动的将该对象转换成HTTP请求参数形式。

 

 

   发表时间:2010-08-18  
LZ实力很强大,继续关注学习。
0 请登录后投票
   发表时间:2010-08-19  
LZ很强大啊,整理的很好啊,你们那些投新手的人啊...
0 请登录后投票
   发表时间:2010-08-19  
良好帖 (1) :: 新手帖 (10) ::

这么多人投新手,这贴挺好的啊。难道je大牛太多了
0 请登录后投票
   发表时间:2010-08-19  
很好很强大。不过愚以为,对于表单的处理可以对任何类型的键值配对都将值做成数组,而不只是checkbox这样处理。因为可能会有重名输入框的情况发生,这样不会导致只有一个值传到服务器上。而对于数组,即便只有一个也不影响系统处理,不是吗?
0 请登录后投票
   发表时间:2010-08-19  
javaDevil 写道
良好帖 (1) :: 新手帖 (10) ::

这么多人投新手,这贴挺好的啊。难道je大牛太多了

x神太多。
0 请登录后投票
   发表时间:2010-08-21  
javaDevil 写道
良好帖 (1) :: 新手帖 (10) ::

这么多人投新手,这贴挺好的啊。难道je大牛太多了



不是大牛太多,是菜鸟太多,,看别人再讲基础的东西,就投新手,基础才是最重要的,难道不知道
0 请登录后投票
   发表时间:2010-08-21  
wu_quanyin 写道
javaDevil 写道
良好帖 (1) :: 新手帖 (10) ::

这么多人投新手,这贴挺好的啊。难道je大牛太多了



不是大牛太多,是菜鸟太多,,看别人再讲基础的东西,就投新手,基础才是最重要的,难道不知道

基础的东西,请发到入门讨论,谢谢。
0 请登录后投票
   发表时间:2010-08-21  
http://www.iteye.com/topic/644429

ray_linn 写道
最近发现自己在javaeye的言辞锋芒锐减了许多,自己也百思不得其解,后来终于发现,原来是最近的小白太多,放眼看去,各个板块里都是小白新手帖,如果一个个去点新手帖的话,估计都要得脉管炎了,而且那种水水的帖子,连开骂的兴趣都没有,抓这种帖子远不如以前抓robbin的“linux可以挂载新硬盘是比windows好的一个优点”这种帖子来得有意思。

介绍新东西,新思路,新想法的东西少了许多,不是谈SSH,就是说Rails,看得一点劲头没有,还是自己搞搞博吧。

0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics