django练手(十八):优化上传方式:使用FormData和ajax实现异步上传
一、优化内容
- 同步上传修改为通过ajax方式实现异步上传。
- 增加了文件的过滤功能。
如:①没有选择文件不能提交。
②选择文件大于10000b给出提示,并清空选择控件,让用户重新选择。
优化思路
- 通过FormData获取表单数据;并通过ajax方式上传。
具体实现
只需要修改前端代码,后端代码无需修改。修改后的前端代码如下:
{% extends 'app/layout/basic.html' %}
{% block content %}
<!--
上传文件的form。
action:后台的地址;
method:发送的方式。上传文件一般用post方式发送;
enctype:即encode type的缩写。意思是编码方式。 multipart/form-data 代表form数据有多种编码方式。
-->
<form name="file" method="post" action="{% url 'app:avatar_upload' %}" enctype="multipart/form-data"
id="form_upload">
{% csrf_token %}
<!--
上传文件的input标签。
type的参数必须是file,代表上传文件。
accept表示允许上传的文件类型。"image/*"代表所用图片类型。
multiple 表示一次可以传多个文件。没有这个参数一次只能上传一个文件。
required 表示在提交前必须选择一个文件
-->
<input type="file" accept="image/*" name="avatar_upload" id="input_upload" multiple required>
<input type="button" value="上传" class="btn btn-default btn-custom" id="btn_upload">
</form>
{% endblock %}
{% block js %}
<script>
$("#btn_upload").click(
function () {
// 实例化一个FormData对象。这个对象包含form的内容。这个数据作为后面ajax上传的数据使用。
let formData = new FormData($("#form_upload")[0]);
// 获取input中上传的内容,类型为FileList
let files = $("#input_upload")[0].files;
// 定义一个数组,用来存储图片大小大于10000b的图片名称
let exceedArr = [];
// files.length==0,表示FileList的长度为0,即没有选择图片。则提示没有选择图片,否则通过ajax进行上传动作。
if (files.length === 0) {
alert("你没有选择图片");
} else {
//依次获取上传图片的大小,如果10000b,则把这个图片的名称存到数组里
for (let i = 0; i < files.length; i++) {
if (files[i].size > 10000) {
exceedArr.push(files[i].name);
}
}
/*
1、如果数组的长度大于0,则把数组中所用的图片名称拼接成一个字符串,并提示用户那些图片的大小超过了,同时清空文件选择控件。
2、如果数组的长度不大于0,则执行上传动作。上传完成后清空文件控件。
*/
if (exceedArr.length > 0) {
let alertStr = '';
for (let i = 0; i < exceedArr.length; i++) {
alertStr = alertStr + exceedArr[i] + ",";
}
alert(alertStr + " 大于10000b,请重新选择");
$("#input_upload").val("");
} else {
$.ajax({
url: "{% url 'app:avatar_upload' %}", //请求路径
type: 'POST', // 请求类型
data: formData, // 请求数据
dataType: "JSON", // 返回数据格式
contentType: false, //表示不处理数据
processData: false,//默认为true,表示会序列化数据。这里设置为false,表示不会序列化数据。
cache: false,
success: function () {
alert("上传成功");
$("#input_upload").val("");
},
error: function (data) {
console.log(data);
}
});
}
}
}
)
</script>
{% endblock %}