javascript - 上传多个文件并显示进度条
问题描述
我正在开发一个项目(在 Django 中),我在其中创建了一个页面来添加有关文件的数据信息,然后添加文件本身。
单击“更多数据集”按钮时,它会添加另一个字段以上传另一个文件。
这样做可以一次性附加最终用户想要的尽可能多的文件。
我需要的是在单击“上传数据集”后上传所有附件,并应显示单个进度条。
到目前为止,我已经浏览了多个教程,但使用Vitor Freitas 的教程已经接近了。
JS代码:
$(function(){
/*$("#add_new_dataset").click(function(){
$(".file").click();
});*/
$(".file").fileupload({
dataType: 'json',
sequentialUploads: true, /* Send the files one by one */
start: function(e){ /* When the upload process starts, show the modal */
$("#modal-progress").modal("show");
},
stop: function(e){ /* When the upload progress finalizes, hide the modal */
$("#modal-progress").modal("hide");
},
progressall: function(e, data){ /* Update the progress bar */
var progress = parseInt(data.loaded / data.total * 100, 10),
strProgress = progress + "%";
$(".progress-bar").css({"width": strProgress});
$(".progress-bar").text(strProgress);
},
done: function(e, data){
if(data.result.is_valid){
$("#gallery tbody").prepend(
"<tr><td><a href='" + data.result.url + "'>" + data.result.name + "</a></td></tr>"
);
}
}
})
});
模板代码:
<form id="form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="container-fluid" id="datasets" style="margin: 0px; padding: 0px;">
<div class="row" onfocusin="populateFilename(this);">
<label class="col-md-2">User Name :</label>
<input class="col-md-2" type="text" id="username" name="user_name" value="{{ user.username }}" readonly />
<label class="col-md-2">Data-set :</label>
<input class="col-md-2" type="text" placeholder="Enter dataset" name="dataset" required />
<label class="col-md-2">Creation Date :</label>
<input class="col-md-2" type="date" placeholder="YYYY-MM-DD" name="creation_date" required />
<label class="col-md-2">Beam Line:</label>
<input class="col-md-2" type="text" placeholder="Enter beam line" name="beamline" required />
<label class="col-md-2">Data-set file:</label>
<input class="col-md-2 file" type="file" name="file" data-url="{% url 'add_data_sets' %}" data-form-data='{"csrfmiddlewaretoken": "{{ csrf_token }}"}' required />
<label class="filename"></label>
<div class="modal fade" id="modal-progress" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Uploading...</h4>
</div>
<div class="modal-body">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%;">0%</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="align: center; margin-top: 5px;">
<div class="container btn-group btn-group-justified btn-group-lg">
<a onmouseup="addRow();" class="btn btn-outline-secondary" style="width: 50%;">More Datasets</a>
<button type="submit" class="btn btn-outline-primary" name="add_new_dataset" id="add_new_dataset">Submit Data-set</button>
</div>
</div>
我应该怎么办?我不太擅长 AJAX,但我看不到任何可以将数据发送到服务器端的代码。是这样还是我错过了什么?请忽略我对这个话题的无知,并提前感谢所有人。
编辑:
已根据一些答案重写了 JS 代码。
document.getElementById('add_new_dataset').onclick = function() {
$(this).preventDefault();
console.log('Files uploading begin');
form_data = new FormData();
const files = document.getElementsByName('file');
let count = 0;
for(let i = 0; i < files.length; i++){
count++;
form_data.append("file", files[i]);
}
$.ajax({
url: "/add_data_sets",
dataType: 'json',
contentType: false,
processData: false,
data: form_data,
type: 'POST',
success: function(files, response, xhr, pd){
$('.file').show();
if(files.status != false){
$('.progress-bar').val('/location/' + files.filename);
var fileData = files.filename;
console.log('Files uploading...');
}
else{
alert(files.filename);
}
},
/*xhrFields: {
onprogress: function(e) {
if(e.lengthComputable) {
let percentCompleted = e.loaded / evt.total;
pBar.style.width = percentComplete;
pBar.innerHTML = percentComplete + "%";
console.log('Percent complete : ' + percentComplete);
}
}
}*/
xhr: function(){
let xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function(e) {
let percentCompleted = e.loaded / evt.total * 100;
pBar.style.width = percentComplete;
pBar.innerHTML = percentComplete + "%";
console.log('Percent complete : ' + percentComplete);
};
return xhr;
}
});
//});
};
这只是上传代码块。从客户端到服务器端的数据发送工作完美,但它令人怀疑,因为当代码运行时没有触发“console.log”调用。是不是数据以某种方式正常提交,而这段代码什么也没做。
EDIT2:
一个新的 JS 函数:
function upload() {
console.log('Upload function begins');
let pBar = document.getElementsByClassName('progress-bar')[0],
progressWindow = document.getElementById('modal-progress'),
formData = new FormData(document.forms.form),
xhr = new XMLHttpRequest(),
percent = 0;
console.log('Form Data created');
// Start upload
xhr.upload.onloadstart = function() {
//$('#modal-progress').hide().fadeIn();
//progressWindow
};
// Track upload progress
xhr.upload.onprogress = function(event) {
percent = parseInt(event.loaded / event.total * 100);
pBar.innerHTML = percent + "%";
pBar.style.width = percent + "%";
//console.log(percent + '% completed');
//console.log('Uploaded event.loaded of event.total');
};
// Report if ends with an error
xhr.upload.onerror = function() {
console.log('An error has occurred')
};
// Track completion: Both successful or not
xhr.upload.onloadend = function() {
//$('#modal-progress').fadeOut().hide();
console.log('Upload complete with or without error ' + xhr.status);
};
// Track progress: Triggered on successful completion
xhr.upload.onload = function() {
console.log('Uploading complete');
progressWindow.hidden = True;
};
xhr.open("POST", "{% url 'add_data_sets' %}", true);
// The 'setRequestHeader' function can only be called when xhr is opened.
//xhr.setRequestHeader('csrfmiddlewaretoken', '{{ csrf_token }}');
//xhr.setRequestHeader('test-info', 'something');
xhr.setRequestHeader('Content-Type', 'application/gzip');
xhr.send(formData);
}
该功能现在工作正常。它发送数据完全正常,但在开发服务器控制台屏幕上我收到此错误。
Forbidden (CSRF token missing or incorrect.): /accounts/add_data_set/
[22/Feb/2020 15:36:06] "POST /accounts/add_data_set/ HTTP/1.1" 403 2513
我什至检查了记录发送到服务器的 POST 数据,它确实包含 csrf 令牌
<QueryDict: {'csrfmiddlewaretoken': ['WREoIV0aY4B2XyrU7d9Qw8kMwiokXqwWsmbc2QSHX5VQ0EaYjjeuv7PeysMJjecp'], 'user_name': ['rakesh'], 'dataset': ['r'], 'creation_date': ['2020-02-22'], 'beamline': ['r']}>
我有点困惑。这是一个问题吗?
解决方案
如果您有任何 fileuploader 插件,他们的文档将包含所有内容,或者如果您想要正常的文件上传输入,您可以通过将文件输入绑定到表单数据来发布它们,然后发布操作表单数据和保存图像的操作,然后您可以返回 save图片和显示,这样就可以实现简单的ajax上传。
var form_data = new FormData();
var totalFiles = document.getElementById('file').files.length;
var count = 0;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById('file').files[i];
count++;
form_data.append("file", file);
}
$.ajax({
url: "/uploadingaction",
dataType: 'json',
contentType: false,
processData: false,
data: form_data,
type: 'POST',
success: function (files, response, xhr, pd) {
$('yourloaderid').hide();
if (files.status != false) {
$('#displayid').val('/location/' + files.filename);
var filedata = files.filename;
} else {
alert(files.filename);
}
}
})
推荐阅读
- python - 代码如何检查字符串是否为回文
- node.js - 从ftp下载文件并在nodejs中使用jsftp和crypto解密
- typescript - 缩小接口的通用联合属性,就好像它是打字稿中的局部变量
- java - Generating a PDF with custom size in android with PdfDocument
- node.js - Use node-gyp with atom
- java - Java Point Errors
- ruby-on-rails - 使用标记作为 :id 的编辑助手没有路由错误(来自 Ruby on rails 教程第三版)
- image - Flutter AssetImage 加载缓慢/白屏
- scala - 无法在 Scala.js 中执行 HmacSHA256 散列
- python - 特定类别中的数据点总数