Javascript 如何将空数组附加到FormData对象?
我有以下问题: 在FormData上使用了N复选框的html表单,用于通过ajax发送包含其信息的请求。在PHP上,$\u POST['teste']变量不存在Javascript 如何将空数组附加到FormData对象?,javascript,php,ajax,form-data,Javascript,Php,Ajax,Form Data,我有以下问题: 在FormData上使用了N复选框的html表单,用于通过ajax发送包含其信息的请求。在PHP上,$\u POST['teste']变量不存在 <form id="teste_form"> <input type="checkbox" name="teste[]"> <input type="checkbox" name="teste[]&qu
<form id="teste_form">
<input type="checkbox" name="teste[]">
<input type="checkbox" name="teste[]">
<input type="checkbox" name="teste[]">
<input type="checkbox" name="teste[]">...
</form>
<script>
var form_data_obj = new FormData( document.getElementById('teste_form') );
$.ajax({
...
data: form_data_obj
...
});
</script>
...
var form_data_obj=新FormData(document.getElementById('teste_form');
$.ajax({
...
数据:表格\数据\对象
...
});
我知道我可以在PHP上使用“if(isset(…)”,但我真的不喜欢这个解决方案。对我来说,最好的解决方案是从FormData对象向PHP发送一个空数组
Obs:我尝试了一些事情,例如:
- 表单_data_obj.append('teste[],未定义)
- 表单_data_obj.append('teste[],0)
var追加=null;
$('.确认预约')。提交(功能(e){
如果(追加!==null)追加。删除();
/************************************/
if($(“输入[name='teste[]']:选中”).length==0){
追加=$(“”)。追加到($(此));
}
/************************************/
e、 预防默认值();
$(this).append(decodeURIComponent($(this).serialize())+'
';
});代码>
即使没有jQuery,这也是绝对可能的
yourFormData.append('key',[]);
我不知道这是否相关,但对于我的实现,以下内容非常有用。在定义空数组之后,它必须循环实际数组,递归地物理声明对象,以适应对象和子数组等
formData.append(key+'[]',[])代码>
所以在现场使用时,我的整个FormData构建看起来像这样
/* ............................................................ */
/* .........runPostFetchScripts Can be used throughout [AF].... */
function runPostFetchScripts(id, str) {
// Try and break out any scripts that need to also be run from the newly acquired HTML body (these don't naturally get run)...
// Find ALL script tags (most basic form ONLY for now)...
//console.log(str);
scripts = str.split('<sc' + 'ript>');
// First element will be content, so remove it
if(scripts.length > 1) {
scripts.splice(0, 1);
one_biggy = "";
for(i = 0; i < scripts.length; ++i) {
// Then get rid of following content after end of script tag
scripter = scripts[i].split("</sc" + "ript>");
// And run what is left...
//console.log(i + ": " + scripter[0]);
one_biggy += scripter[0];
}
//console.log(one_biggy);
eval(one_biggy);
}
// Phew! This took way longer than expected [AF]!
}
/* ............................................................ */
/* .........New inclusion for FormData Validation and addition of Files, Multiple Files and Arrays to Form uploads via Ajax.... */
function genericBuildFormData(formData, data, previousKey) {
/*
console.log("genericBuildFormData(");
console.log(formData);
console.log(data);
console.log(previousKey);
//*/
if(data instanceof File) {
//console.log(previousKey + " file append...");
formData.append(previousKey, data);
} else if (data instanceof Object) {
var keys = Object.keys(data);
for(var k = 0; k < keys.length; ++k) {
var key = keys[k];
var value = data[key];
/*
console.log(k + " " + key);
console.log(!(value instanceof File));
console.log(value instanceof Object);
console.log(!(Array.isArray(value)));
console.log(value);
//*/
if(previousKey != '') {
key = previousKey + '[' + key + ']';
}
if (!(value instanceof File) && (value instanceof Object) && !(Array.isArray(value))) {
//console.log("Is Object, go again... " + key + "[]");
formData.append(key + '[]', []);
genericBuildFormData(formData, value, key);
} else {
if (Array.isArray(value)) {
//console.log(key + " is Array...");
// Define empty array first...
formData.append(key + '[]', []);
// Now loop through all array contents, accounting for embedded objects and sub-arrays...
for (var a = 0; a < value.length; ++a) {
//console.log(a);
genericBuildFormData(formData, value[a], key + '[' + a + ']');
}
} else {
//console.log(key + " append...");
formData.append(key, value);
}
}
}
} else {
//console.log(previousKey + ": " + data + " append...");
formData.append(previousKey, data);
}
}
/* ............................................................ */
/* .............genericAjaxCall Can be used throughout [AF].... */
function genericAjaxCall(GetPost, FullUrl, PostParams, Container, id, callback) {
/*
console.log("genericAjaxCall(...");
console.log(FullUrl);
console.log(PostParams);
console.log(Container);
console.log(id);
//*/
var GET_POST = GetPost.toUpperCase();
var jacks = {
url: FullUrl,
type: GET_POST,
async: true,
processData: false, // Due to contentType, assume WE have got the data right, so do not allow AJAX to find fault with what we have done (files and arrays will fail otherwise) [AF]
contentType: false, // Let Ajax work this out for us seeing as we are going to be mixing arrays, objects and files as well as primitives, so don't tell it anything [AF]
success: function(strResult) {
populateContainer = (Container ? document.getElementById(Container) : false);
//console.log(populateContainer);
if(populateContainer) {
//populateContainer.innerHTML = ""; // To drop possible scroll values
populateContainer.innerHTML = strResult;
//console.log(strResult);
if(callback != null) {
window.setTimeout(function() {
callback(id, strResult);
}, 100);
}
} else {
//console.log("ajax.strResult: " + FullUrl + " " + id + " = " + strResult);
if(callback != null) {
window.setTimeout(function() {
callback(id, strResult);
}, 100);
}
}
},
error: function(jqXHR, textStatus, errorThrown) {
populateContainer = document.getElementById(Container);
if(populateContainer) {
populateContainer.innerHTML = "Error: " + textStatus + " - " + errorThrown;
} else {
if(callback != null) {
window.setTimeout(function() {
callback(id, null, 'Error: ' + textStatus + ' - ' + errorThrown);
}, 100);
} else {
console.log('Error: ' + textStatus + ' - ' + errorThrown);
}
}
}
};
if(GET_POST == "POST") {
//console.log(PostParams);
// Use FormData for File Upload inclusion
var myFormData = new FormData();
genericBuildFormData(myFormData, PostParams, '');
jacks.processData = false;
jacks.contentType = false;
jacks.data = myFormData;
}
//console.log(jacks);
$.ajax(jacks);
}
additional[]:
additional[0]: null
additional[1][id]: 7715
additional[1][ex]: Permanent Exclusion
additional[1][mi]: 1
additional[2]: null
additional[3]: null
additional[4]: null
在chrome的“网络头”(提交时)中查看的结果数据如下所示
/* ............................................................ */
/* .........runPostFetchScripts Can be used throughout [AF].... */
function runPostFetchScripts(id, str) {
// Try and break out any scripts that need to also be run from the newly acquired HTML body (these don't naturally get run)...
// Find ALL script tags (most basic form ONLY for now)...
//console.log(str);
scripts = str.split('<sc' + 'ript>');
// First element will be content, so remove it
if(scripts.length > 1) {
scripts.splice(0, 1);
one_biggy = "";
for(i = 0; i < scripts.length; ++i) {
// Then get rid of following content after end of script tag
scripter = scripts[i].split("</sc" + "ript>");
// And run what is left...
//console.log(i + ": " + scripter[0]);
one_biggy += scripter[0];
}
//console.log(one_biggy);
eval(one_biggy);
}
// Phew! This took way longer than expected [AF]!
}
/* ............................................................ */
/* .........New inclusion for FormData Validation and addition of Files, Multiple Files and Arrays to Form uploads via Ajax.... */
function genericBuildFormData(formData, data, previousKey) {
/*
console.log("genericBuildFormData(");
console.log(formData);
console.log(data);
console.log(previousKey);
//*/
if(data instanceof File) {
//console.log(previousKey + " file append...");
formData.append(previousKey, data);
} else if (data instanceof Object) {
var keys = Object.keys(data);
for(var k = 0; k < keys.length; ++k) {
var key = keys[k];
var value = data[key];
/*
console.log(k + " " + key);
console.log(!(value instanceof File));
console.log(value instanceof Object);
console.log(!(Array.isArray(value)));
console.log(value);
//*/
if(previousKey != '') {
key = previousKey + '[' + key + ']';
}
if (!(value instanceof File) && (value instanceof Object) && !(Array.isArray(value))) {
//console.log("Is Object, go again... " + key + "[]");
formData.append(key + '[]', []);
genericBuildFormData(formData, value, key);
} else {
if (Array.isArray(value)) {
//console.log(key + " is Array...");
// Define empty array first...
formData.append(key + '[]', []);
// Now loop through all array contents, accounting for embedded objects and sub-arrays...
for (var a = 0; a < value.length; ++a) {
//console.log(a);
genericBuildFormData(formData, value[a], key + '[' + a + ']');
}
} else {
//console.log(key + " append...");
formData.append(key, value);
}
}
}
} else {
//console.log(previousKey + ": " + data + " append...");
formData.append(previousKey, data);
}
}
/* ............................................................ */
/* .............genericAjaxCall Can be used throughout [AF].... */
function genericAjaxCall(GetPost, FullUrl, PostParams, Container, id, callback) {
/*
console.log("genericAjaxCall(...");
console.log(FullUrl);
console.log(PostParams);
console.log(Container);
console.log(id);
//*/
var GET_POST = GetPost.toUpperCase();
var jacks = {
url: FullUrl,
type: GET_POST,
async: true,
processData: false, // Due to contentType, assume WE have got the data right, so do not allow AJAX to find fault with what we have done (files and arrays will fail otherwise) [AF]
contentType: false, // Let Ajax work this out for us seeing as we are going to be mixing arrays, objects and files as well as primitives, so don't tell it anything [AF]
success: function(strResult) {
populateContainer = (Container ? document.getElementById(Container) : false);
//console.log(populateContainer);
if(populateContainer) {
//populateContainer.innerHTML = ""; // To drop possible scroll values
populateContainer.innerHTML = strResult;
//console.log(strResult);
if(callback != null) {
window.setTimeout(function() {
callback(id, strResult);
}, 100);
}
} else {
//console.log("ajax.strResult: " + FullUrl + " " + id + " = " + strResult);
if(callback != null) {
window.setTimeout(function() {
callback(id, strResult);
}, 100);
}
}
},
error: function(jqXHR, textStatus, errorThrown) {
populateContainer = document.getElementById(Container);
if(populateContainer) {
populateContainer.innerHTML = "Error: " + textStatus + " - " + errorThrown;
} else {
if(callback != null) {
window.setTimeout(function() {
callback(id, null, 'Error: ' + textStatus + ' - ' + errorThrown);
}, 100);
} else {
console.log('Error: ' + textStatus + ' - ' + errorThrown);
}
}
}
};
if(GET_POST == "POST") {
//console.log(PostParams);
// Use FormData for File Upload inclusion
var myFormData = new FormData();
genericBuildFormData(myFormData, PostParams, '');
jacks.processData = false;
jacks.contentType = false;
jacks.data = myFormData;
}
//console.log(jacks);
$.ajax(jacks);
}
additional[]:
additional[0]: null
additional[1][id]: 7715
additional[1][ex]: Permanent Exclusion
additional[1][mi]: 1
additional[2]: null
additional[3]: null
additional[4]: null
。。。其中数组元素0,2,3,4为空,元素1为嵌入对象
希望这有帮助。Shalom.PHP错误:array_filter()希望参数1是数组,字符串给定。。。但即便如此,我的PHP代码还是通用的。我不想更改它,直到我确定不能通过FormData发送空数组。这与PHP无关。表单数据中的空数组会导致一个空字符串——正如开发者工具的网络选项卡所示。带有空值的隐藏输入对我帮助很大,它值得一次投票,但我正在搜索的解决方案是使用JS,类似于form_data.append('test',[]),并在PHP上接收,无需处理,$\u POST['test']=[].更新了我的答案。我希望在表单字段名称中指定索引。。。然后,您将通过选中的值确切地知道属于哪个“位置”。如果在PHP中对数组执行foreach
,则“缺少”索引不是真正的问题。