这几天做一个Ajax像服务器动态提交的表单然后给出即时反馈.这些表单内容都是一系列的.内容大同小异.所以代码和页面结构也是大同小异.但是其中有一个页面使用AJAX始终无法提取到服务器值.反而将此页的整个render出来的页面显示出来.关键代码如下:
Code
$(document).ready(function() {
$("#Submit").click(function() {
var a = $("#aspnetForm").serialize();
/*因为使用了masterpage,所以页面form的ID为aspnetForm*/
$.ajax({
url: "xxx.aspx",
type: "get",
data: a,
success: function(data){
$("#result").html(data);
}
});
});
});
后台代码简略如下.只是为了让大家明白意思:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["length"] != null)
{
Response.Clear();
Response.Write("这里是回传的数据");
Response.End();
}
}
刚开始我挺奇怪.为什么几个页面都好好的.但是这个页面无论如何也无法收到queryString的值,我干脆将jquery代码重写了一遍.问题依旧.
后来发现在IE里不行.但是在FF里却没事..
用IE的httpwatch插件观察.发现表单无法提取到值.百思不得其解.以为是JQuery库的问题.换了.问题依旧.
上了asp.net的论坛和jquery论坛发邮件.有人说是utf-8编码问题.试了.还是无效-.-!!
最终我只能用“滚雷"的方法,看为什么其他页面行而这个不行.把一个个的html控件挨个删除.然后用httpwatch观察值,最终发现在
<input id="length" type="text" class="txt" name="length" />
这个html控件上出了问题.如果页面里有这个控件serialize方法就无法提取任何值.
恩.对了.你们也肯定想到了.length是js数组的属性关键字.肯定冲突了.
打开js代码,发现原来serialize是用param方法对serializeArray的一个简单包装.
param方法的js代码:
param: function( a ) {
/// <summary>
/// This method is internal. Use serialize() instead.
/// </summary>
/// <param name="a" type="Map">A map of key/value pairs to serialize into a string.</param>'
/// <returns type="String" />
/// <private />
var s = [ ];
function add( key, value ){
s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
};
// If an array was passed in, assume that it is an array
// of form elements
if ( jQuery.isArray(a) || a.jquery )
// Serialize the form elements
jQuery.each( a, function(){
add( this.name, this.value );
});
// Otherwise, assume that it's an object of key/value pairs
else
// Serialize the key/values
for ( var j in a )
// If the value is an array then the key names need to be repeated
if ( jQuery.isArray(a[j]) )
jQuery.each( a[j], function(){
add( j, this );
});
else
add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
// Return the resulting serialization
return s.join("&").replace(/%20/g, "+");
}
serializeArray方法的jquery定义
serializeArray: function() {
/// <summary>
/// Serializes all forms and form elements but returns a JSON data structure.
/// </summary>
/// <returns type="String">A JSON data structure representing the serialized items.</returns>
return this.map(function(){
return this.elements ? jQuery.makeArray(this.elements) : this;
})
.filter(function(){
return this.name && !this.disabled &&
(this.checked || /select|textarea/i.test(this.nodeName) ||
/text|hidden|password|search/i.test(this.type));
})
.map(function(i, elem){
var val = jQuery(this).val();
return val == null ? null :
jQuery.isArray(val) ?
jQuery.map( val, function(val, i){
return {name: elem.name, value: val};
}) :
{name: elem.name, value: val};
}).get();
}
发现问题都不出在这两个函数上.继续跟踪..发现问题出在这serializeArray方法里调用的makeArray方法上
JQuery定义如下
makeArray: function( array ) {
/// <summary>
/// Turns anything into a true array. This is an internal method.
/// </summary>
/// <param name="array" type="Object">Anything to turn into an actual Array</param>
/// <returns type="Array" />
/// <private />
var ret = []; if( array != null ){
var i = array.length;
//问题就出在这
if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
ret[0] = array;
else
while( i )
ret[--i] = array[i];
}
return ret;
}
自习看makeArray的代码.发现这行
var i = array.length;
问题就处在这
因为变量i是取传入的array数组的长度.
而我们知道.js中的array本质上就是一个对象.所以array["length"]和array.length是同一种东西
所以当我将textbox中的id设置为length时.这时就会和对象的length属性重名.造成变量I在下面的计算中出错.自然就返回空了.
解决方法:将textbox的ID换成其他的值
-----------------------------------------------------------
写在后面:这个问题让我快用头撞墙了.刚开始还以为是灵异现象.重启动了好几次-.-!!
分享一下.希望对大家有帮助.