问题“序列化”是将数据对象转换为字符串表示的行为。jQuery自动序列化data
属性,然后再发送AJAX请求。然后服务器反序列化GET
来自URL的querystring和的请求正文POST
在填充PHP的请求变量之前请求。
您的代码在以下情况下按预期运行data
仅由序列化的表单数据(即。data: newFormRecherche,
) 因为数据已经是字符串格式,因此无法进一步序列化。然后服务器的反序列化过程将表单数据正确解析为请求变量。
但是,当data
参数是一个对象,jQuery必须将其序列化才能将其传递给服务器。作为该对象的一个属性,预序列化的表单数据的处理方式就像处理任何其他字符串一样,具体来说,它的转义方式可以防止它被“误认为”是序列化对象。所以当服务器反序列化时data
, newFormRecherche
反序列化为jQuery最初作为字符串接收的值,因此需要进行第二次反序列化,这是@Czerspaluate在注释中提到的,以便生成表单数据的关联数组。
要防止表单数据的双重序列化,请通过调用jQuery\'s .serializeArray()
method 在form元素上,而不是.serialize()
.
而jQuery能够正确序列化data
, 当这样一个数组嵌套为data
对象(而不是发送字符串\'[object Object]\'
替换每个键/值对),以及尝试在另一个键/值数组中嵌套这样的键/值数组时。因此,我认为将表单数据作为多维数据的一部分发送的最佳方法是将键/值数组转换为对象。
所有这些都可以通过以下方式完成:
function ajaxSubmit() {
var newFormRecherche = jQuery( this ).serializeArray();
jQuery.ajax({
type:"POST",
data: {
action: "mon_action",
newFormRecherche: formFieldsToObject( newFormRecherche )
},
url: ajaxurl,
success: function( response ){
console.log( response );
}
});
return false;
}
function formFieldsToObject( fields ) {
var product = {};
for( var i = 0; i < fields.length; i++ ) {
var field = fields[ i ];
if( ! product.hasOwnProperty( field.name ) ) {
product[ field.name ] = field.value;
}
else {
if( ! product[ field.name ] instanceof Array )
product[ field.name ] = [ product[ field.name ] ];
product[ field.name ].push( field.value );
}
}
return product;
}
HTML5
FormData
或者,如果您只需要支持现代浏览器,或者不介意加载polyfill来支持旧浏览器,只需使用
the FormData
object 要将表单数据作为适当的数据对象传递,请执行以下操作:
function ajaxSubmit() {
var newFormRecherche = new FormData( this );
jQuery.ajax({
type:"POST",
data: {
action: "mon_action",
newFormRecherche: newFormRecherche
},
url: ajaxurl,
success: function( response ){
console.log( response );
}
});
return false;
}
服务器端双重反序列化正如@Czersplace在评论中所建议的那样,通过简单地手动反序列化服务器上的表单数据来解释双重序列化也是一个完全有效的解决方案:
add_action( \'wp_ajax_mon_action\', \'mon_action\' );
add_action( \'wp_ajax_nopriv_mon_action\', \'mon_action\' );
function mon_action() {
if( isset( $_POST[ \'newFormRecherche\' ] ) ) {
parse_str( $_POST[ \'newFormRecherche\' ], $newFormRecherche );
die( json_encode( $newFormRecherche ) );
}
}
我倾向于认为其他方法更“专业”,因为发送到服务器的所有数据都是以一致和预期的格式打包的——服务器不需要额外的“解码”,从而提高代码模块化。
但是代码模块化和主观的“专业性”并不总是最重要的因素,有时最简单的解决方案是最合适的。
记住validate and sanitize request
data 在使用服务器之前,请先在服务器上安装,以减轻安全漏洞。