使用
AJAX上传多个图像有很多问题.我写这段代码:
<form id="upload" method="post" enctype="multipart/form-data"> <div id="drop" class="drop-area"> <div class="drop-area-label"> Drop image here </div> <input type="file" name="file" id="file" multiple/> </div> <ul class="gallery-image-list" id="uploads"> <!-- The file uploads will be shown here --> </ul> </form> <div id="listTable"></div>
jQuery的/ AJAX
$(document).on("change","input[name^='file']",function(e){ e.preventDefault(); var This = this,display = $("#uploads"); // list all file data $.each(This.files,function(i,obj){ // for each image run script asynchronous (function(i) { // get data from input file var file = This.files[i],name = file.name,size = file.size,type = file.type,lastModified = file.lastModified,lastModifiedDate = file.lastModifiedDate,webkitRelativePath = file.webkitRelativePath,slice = file.slice,i = i; // DEBUG /* var acc = [] $.each(file,function(index,value) { acc.push(index + ": " + value); }); alert(JSON.stringify(acc)); */ $.ajax({ url:'/ajax/upload.PHP',contentType: "multipart/form-data",data:{ "image": { "name":name,"size":size,"type":type,"lastModified":lastModified,"lastModifiedDate":lastModifiedDate,"webkitRelativePath":webkitRelativePath,//"slice":slice,} },type: "POST",// Custom XMLHttpRequest xhr: function() { var myXhr = $.ajaxSettings.xhr(); // Check if upload property exists if(myXhr.upload) { // For handling the progress of the upload myXhr.upload.addEventListener("progress",progressHandlingFunction,false); } return myXhr; },cache: false,success : function(data){ // load ajax data $("#listTable").append(data); } }); // display progress function progressHandlingFunction(e){ if(e.lengthComputable){ var perc = Math.round((e.loaded / e.total)*100); perc = ( (perc >= 100) ? 100 : ( (perc <= 0) ? 0 : 0 ) ); $("#progress"+i+" > div") .attr({"aria-valuenow":perc}) .css("width",perc+"%"); } } // display list of files display.append('<li>'+name+'</li><div class="progress" id="progress'+i+'">' +'<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">' +'</div></div>'); })(i); }); });
我尝试了各种版本,但我从未成功通过ajax发送多个数据.我已经尝试过你在上面看到的内容,现在我只获得了POST信息.我理解为什么我会收到POST,但我需要发送FILES信息,我不知道我哪里错了.
我第一次使用ajax工作并经常在大多数项目中使用它,但我从来没有用过发送多个文件而现在困扰我.
谢谢!
解决方法@H_404_18@
尝试利用json上传,处理文件对象
HTML
<div id="drop" class="drop-area ui-widget-header">
<div class="drop-area-label">Drop image here</div>
</div>
<br />
<form id="upload">
<input type="file" name="file" id="file" multiple="true" accepts="image/*" />
<ul class="gallery-image-list" id="uploads">
<!-- The file uploads will be shown here -->
</ul>
</form>
<div id="listTable"></div>
CSS
#uploads {
display:block;
position:relative;
}
#uploads li {
list-style:none;
}
#drop {
width: 90%;
height: 100px;
padding: 0.5em;
float: left;
margin: 10px;
border: 8px dotted grey;
}
#drop.hover {
border: 8px dotted green;
}
#drop.err {
border: 8px dotted orangered;
}
JS
var display = $("#uploads"); // cache `#uploads`,`this` at `$.ajax()`
var droppable = $("#drop")[0]; // cache `#drop` selector
$.ajaxSetup({
context: display,contentType: "application/json",dataType: "json",beforeSend: function (jqxhr,settings) {
// pre-process `file`
var file = JSON.parse(
decodeURIComponent(settings.data.split(/=/)[1])
);
// add `progress` element for each `file`
var progress = $("<progress />",{
"class": "file-" + (!!$("progress").length
? $("progress").length
: "0"),"min": 0,"max": 0,"value": 0,"data-name": file.name
});
this.append(progress,file.name + "<br />");
jqxhr.name = progress.attr("class");
}
});
var processFiles = function processFiles(event) {
event.preventDefault();
// process `input[type=file]`,`droppable` `file`
var files = event.target.files || event.dataTransfer.files;
var images = $.map(files,function (file,i) {
var reader = new FileReader();
var dfd = new $.Deferred();
reader.onload = function (e) {
dfd.resolveWith(file,[e.target.result])
};
reader.readAsDataURL(new Blob([file],{
"type": file.type
}));
return dfd.then(function (data) {
return $.ajax({
type: "POST",url: "/echo/json/",data: {
"file": JSON.stringify({
"file": data,"name": this.name,"size": this.size,"type": this.type
})
},xhr: function () {
// do `progress` event stuff
var uploads = this.context;
var progress = this.context.find("progress:last");
var xhrUpload = $.ajaxSettings.xhr();
if (xhrUpload.upload) {
xhrUpload.upload.onprogress = function (evt) {
progress.attr({
"max": evt.total,"value": evt.loaded
})
};
xhrUpload.upload.onloadend = function (evt) {
var progressData = progress.eq(-1);
console.log(progressData.data("name")
+ " upload complete...");
var img = new Image;
$(img).addClass(progressData.eq(-1)
.attr("class"));
img.onload = function () {
if (this.complete) {
console.log(
progressData.data("name")
+ " preview loading..."
);
};
};
uploads.append("<br /><li>",img,"</li><br />");
};
}
return xhrUpload;
}
})
.then(function (data,textStatus,jqxhr) {
console.log(data)
this.find("img[class=" + jqxhr.name + "]")
.attr("src",data.file)
.before("<span>" + data.name + "</span><br />");
return data
},function (jqxhr,errorThrown) {
console.log(errorThrown);
return errorThrown
});
})
});
$.when.apply(display,images).then(function () {
var result = $.makeArray(arguments);
console.log(result.length,"uploads complete");
},function err(jqxhr,errorThrown) {
console.log(jqxhr,errorThrown)
})
};
$(document)
.on("change","input[name^=file]",processFiles);
// process `droppable` events
droppable.ondragover = function () {
$(this).addClass("hover");
return false;
};
droppable.ondragend = function () {
$(this).removeClass("hover")
return false;
};
droppable.ondrop = function (e) {
$(this).removeClass("hover");
var image = Array.prototype.slice.call(e.dataTransfer.files)
.every(function (img,i) {
return /^image/.test(img.type)
});
e.preventDefault();
// if `file`,file type `image`,process `file`
if (!!e.dataTransfer.files.length && image) {
$(this).find(".drop-area-label")
.css("color","blue")
.html(function (i,html) {
$(this).delay(3000,"msg").queue("msg",function () {
$(this).css("color","initial").html(html)
}).dequeue("msg");
return "File dropped,processing file upload...";
});
processFiles(e);
} else {
// if dropped `file` _not_ `image`
$(this)
.removeClass("hover")
.addClass("err")
.find(".drop-area-label")
.css("color","darkred")
.html(function (i,"initial").html(html)
.parent("#drop").removeClass("err")
}).dequeue("msg");
return "Please drop image file...";
});
};
};
<?PHP
if (isset($_POST["file"])) {
// do PHP stuff
// call `json_encode` on `file` object
$file = json_encode($_POST["file"]);
// return `file` as `json` string
echo $file;
};
HTML
<div id="drop" class="drop-area ui-widget-header"> <div class="drop-area-label">Drop image here</div> </div> <br /> <form id="upload"> <input type="file" name="file" id="file" multiple="true" accepts="image/*" /> <ul class="gallery-image-list" id="uploads"> <!-- The file uploads will be shown here --> </ul> </form> <div id="listTable"></div>
CSS
#uploads { display:block; position:relative; } #uploads li { list-style:none; } #drop { width: 90%; height: 100px; padding: 0.5em; float: left; margin: 10px; border: 8px dotted grey; } #drop.hover { border: 8px dotted green; } #drop.err { border: 8px dotted orangered; }
JS
var display = $("#uploads"); // cache `#uploads`,`this` at `$.ajax()` var droppable = $("#drop")[0]; // cache `#drop` selector $.ajaxSetup({ context: display,contentType: "application/json",dataType: "json",beforeSend: function (jqxhr,settings) { // pre-process `file` var file = JSON.parse( decodeURIComponent(settings.data.split(/=/)[1]) ); // add `progress` element for each `file` var progress = $("<progress />",{ "class": "file-" + (!!$("progress").length ? $("progress").length : "0"),"min": 0,"max": 0,"value": 0,"data-name": file.name }); this.append(progress,file.name + "<br />"); jqxhr.name = progress.attr("class"); } }); var processFiles = function processFiles(event) { event.preventDefault(); // process `input[type=file]`,`droppable` `file` var files = event.target.files || event.dataTransfer.files; var images = $.map(files,function (file,i) { var reader = new FileReader(); var dfd = new $.Deferred(); reader.onload = function (e) { dfd.resolveWith(file,[e.target.result]) }; reader.readAsDataURL(new Blob([file],{ "type": file.type })); return dfd.then(function (data) { return $.ajax({ type: "POST",url: "/echo/json/",data: { "file": JSON.stringify({ "file": data,"name": this.name,"size": this.size,"type": this.type }) },xhr: function () { // do `progress` event stuff var uploads = this.context; var progress = this.context.find("progress:last"); var xhrUpload = $.ajaxSettings.xhr(); if (xhrUpload.upload) { xhrUpload.upload.onprogress = function (evt) { progress.attr({ "max": evt.total,"value": evt.loaded }) }; xhrUpload.upload.onloadend = function (evt) { var progressData = progress.eq(-1); console.log(progressData.data("name") + " upload complete..."); var img = new Image; $(img).addClass(progressData.eq(-1) .attr("class")); img.onload = function () { if (this.complete) { console.log( progressData.data("name") + " preview loading..." ); }; }; uploads.append("<br /><li>",img,"</li><br />"); }; } return xhrUpload; } }) .then(function (data,textStatus,jqxhr) { console.log(data) this.find("img[class=" + jqxhr.name + "]") .attr("src",data.file) .before("<span>" + data.name + "</span><br />"); return data },function (jqxhr,errorThrown) { console.log(errorThrown); return errorThrown }); }) }); $.when.apply(display,images).then(function () { var result = $.makeArray(arguments); console.log(result.length,"uploads complete"); },function err(jqxhr,errorThrown) { console.log(jqxhr,errorThrown) }) }; $(document) .on("change","input[name^=file]",processFiles); // process `droppable` events droppable.ondragover = function () { $(this).addClass("hover"); return false; }; droppable.ondragend = function () { $(this).removeClass("hover") return false; }; droppable.ondrop = function (e) { $(this).removeClass("hover"); var image = Array.prototype.slice.call(e.dataTransfer.files) .every(function (img,i) { return /^image/.test(img.type) }); e.preventDefault(); // if `file`,file type `image`,process `file` if (!!e.dataTransfer.files.length && image) { $(this).find(".drop-area-label") .css("color","blue") .html(function (i,html) { $(this).delay(3000,"msg").queue("msg",function () { $(this).css("color","initial").html(html) }).dequeue("msg"); return "File dropped,processing file upload..."; }); processFiles(e); } else { // if dropped `file` _not_ `image` $(this) .removeClass("hover") .addClass("err") .find(".drop-area-label") .css("color","darkred") .html(function (i,"initial").html(html) .parent("#drop").removeClass("err") }).dequeue("msg"); return "Please drop image file..."; }); }; };
<?PHP if (isset($_POST["file"])) { // do PHP stuff // call `json_encode` on `file` object $file = json_encode($_POST["file"]); // return `file` as `json` string echo $file; };