您对 $("#form").serialize() 的想法是正确的,但对于(仍然)AJAX 上传的混乱。糟糕(我很惭愧第一次没有注意到那个细节:-()。
通过 AJAX 上传文件的问题是(通常情况下)Internet Explorer。基本上,它直到 IE10 才支持 FormData 对象(这意味着,如果您关心支持 XP 用户,他们最好运行非 IE)。 FormData 大大简化了通过 AJAX 上传东西的过程;如果你没有,这里是你的选择:
- 在页面上放置一个小小的 IFRAME,并为实际的文件上传进行管理。
- 使用 JSON 等以编程方式对表单数据进行编码,然后通过 jQuery 发送。
- 使用 nice plugin 为您包装这一切(并在幕后使用这些技术中的一种或多种)。
我将假设您不关心 IE8/9(几乎其他所有人都不是问题)并为您提供 FormData 解决方案。与之前的编辑不同,我在这里弹出整个函数,因为它提供了相当多的信息。这种特殊的解决方案会上传整个表单,将现有字段拉入 FormData 对象并特殊处理文件。
<!-- Many ways to skin this particular feline; I like this one :-) -->
<form onsubmit="return uploadFiles(this)">
<!-- Access from PHP using $_FILES["somefile"]["name"][$idx]... -->
<input type="file" name="somefiles" multiple="1" />
</form>
<script>
// Function to upload a form via FormData, breaking out files and cutting
// any non-named elements. Assumes that there's a #status DIV and the
// URL is hardcoded.
function uploadFiles(frm) {
var formdata = new FormData();
// I'm doing this to separate out the upload content. Note that multiple
// files can be uploaded and will appear as a decently-friendly PHP array
// in $_FILES. Note also that this does handle multiple files properly
// (a default FormData(frm) wouldn't exactly :-( ).
$(frm).find(":input").each(function(idx, ele) {
// This is a file field. Break it out.
if(ele.files) {
for(i=0; i<ele.files.length; i++) {
formdata.append(ele.name + "[" + i + "]", ele.files[i]);
}
// Not a file element, so put in the upload iff there's a name.
} else if(ele.name) {
formdata.append(ele.name, ele.value);
}
});
// Run the AJAX.
$.ajax({
url: "test.php", // Change Me :-)
type: "POST",
data: formdata,
processData: false, // Need these to keep jQuery from messing up your form
contentType: false,
success: function(data) {
$("#status").html(data);
},
error: function(xhr, status, error) {
$("#status").html("Error uploading file(s): " + error);
},
});
return false; // Keep the form from submitting
}
</script>
我有一个完整的 HTML 文件和相应的 PHP,它们在 pastebin 工作。
如果我是你,如果可以的话,我实际上只会使用Sebastian's jQuery File Upload。它拥有现代 UI 的所有优点(包括进度计量)、浏览器抽象,并且获得了 MIT 许可启动。也就是说,如果您只需要一些东西来复制意大利面,这个答案会让您上路。祝你好运!