Mar*_*ark 29 html ajax jquery file-upload asyncfileupload
我有一个多文件上传表单:
<input type="file" name="files" multiple />
Run Code Online (Sandbox Code Playgroud)
我用ajax发布这些文件.我想逐个上传所选文件(创建单独的进度条,并且出于好奇心).
我可以通过以下方式获取文件列表或单个文件
FL = form.find('[type="file"]')[0].files
F = form.find('[type="file"]')[0].files[0]
Run Code Online (Sandbox Code Playgroud)
yieling
FileList { 0=File, 1=File, length=2 }
File { size=177676, type="image/jpeg", name="img.jpg", more...}
Run Code Online (Sandbox Code Playgroud)
但FileList是不可变的,我无法弄清楚如何提交单个文件.
我认为这是可能的,因为我看到http://blueimp.github.com/jQuery-File-Upload/.我不想使用这个插件,因为它与学习结果一样多(而且无论如何都需要太多的custimizing).我也不想使用Flash.
poc*_*sar 31
要使其成为同步操作,您需要在完成最后一次操作时启动新传输.例如,Gmail会同时发送所有内容.对AJAX的文件上传进度的事件progress或onprogress对原始XmlHttpRequest实例.
因此,在$.ajax()服务器端(我不知道你将使用什么)之后,发送一个JSON响应以在下一个输入上执行AJAX.一种选择是对AJAX元素结合到每一个元素,使事情变得更容易,所以你可以只是做在success了$(this).sibling('input').execute_ajax().
像这样的东西:
$('input[type="file"]').on('ajax', function(){
var $this = $(this);
$.ajax({
'type':'POST',
'data': (new FormData()).append('file', this.files[0]),
'contentType': false,
'processData': false,
'xhr': function() {
var xhr = $.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener('progress', progressbar, false);
}
return xhr;
},
'success': function(){
$this.siblings('input[type="file"]:eq(0)').trigger('ajax');
$this.remove(); // remove the field so the next call won't resend the same field
}
});
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each
Run Code Online (Sandbox Code Playgroud)
上面的代码是多个<input type="file">但不是<input type="file" multiple>,在这种情况下,它应该是:
var count = 0;
$('input[type="file"]').on('ajax', function(){
var $this = $(this);
if (typeof this.files[count] === 'undefined') { return false; }
$.ajax({
'type':'POST',
'data': (new FormData()).append('file', this.files[count]),
'contentType': false,
'processData': false,
'xhr': function() {
var xhr = $.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener('progress', progressbar, false);
}
return xhr;
},
'success': function(){
count++;
$this.trigger('ajax');
}
});
}).trigger('ajax'); // Execute only the first input[multiple] AJAX, we aren't using $.each
Run Code Online (Sandbox Code Playgroud)
注意到,并非所有浏览器都支持通过vanilla ajax上传,我仍然建议使用iframe.(IE动态创建iframe并使用javascript对其进行POST)
我一直在使用这个脚本,我发现它非常简洁.如果您想通过创建iframe了解如何上传,您应该深入了解它的来源.
希望能帮助到你 :)
额外编辑
要使用iframe方法创建进度条,您需要在服务器端执行一些工作.如果你使用的是php,你可以使用:
如果使用nginx,您还可以选择使用他们的上传进度模块进行编译
所有这些都以相同的方式工作 - 每次上传都有一个UID,您将通过ajax以一致的间隔请求与该ID相关联的"进度".这将返回服务器确定的上载进度.
小智 5
我遇到了同样的问题,并提供了这个解决方案。我只是用 multipart 检索表单,并在递归调用(文件后文件)中启动 ajax 请求,它只在完成时调用 next 。
var form = document.getElementById( "uploadForm" );
var fileSelect = document.getElementById( "photos" );
var uploadDiv = document.getElementById( "uploads" );
form.onsubmit = function( event ) {
event.preventDefault( );
var files = fileSelect.files;
handleFile( files, 0 );
};
function handleFile( files, index ) {
if( files.length > index ) {
var formData = new FormData( );
var request = new XMLHttpRequest( );
formData.append( 'photo', files[ index ] );
formData.append( 'serial', index );
formData.append( 'upload_submit', true );
request.open( 'POST', 'scripts/upload_script.php', true );
request.onload = function( ) {
if ( request.status === 200 ) {
console.log( "Uploaded" );
uploadDiv.innerHTML += files[ index ].name + "<br>";
handleFile( files, ++index );
} else {
console.log( "Error" );
}
};
request.send( formData );
}
}
Run Code Online (Sandbox Code Playgroud)