目录
大文件切片上传和断点续传
axios的二次封装
在项目中我们通常使用的文件上传的格式为FormData,我们可以通过创建FormData类的实例进行,再通过实例的append方法将和后端开发者约束的字段名进行添加,如下:
let fm = new FormData();
fm.append('file','');
在传递FormData格式的数据时,需要在请求时添加请求头Content-Type:multipart/form-data告知服务器要传递的数据格式,但为了避免每一次请求都要手动添加这个请求头,所以我们要对一些公共的消息进行提取,对axios进行二次封装;
我们需要使用axios.create创建一个axios实例,这样就可以避免和其它的axios模块发生冲突,随后统一设置请求头;
上传文件多使用post请求,如果需要对post请求的请求体的内容做转换,转化成想要的指定的urlencoded格式,可以使用transformRequest,配合指定的插件Qs进行转化。例如:请求体内容为{file:'xxx',filename:'xxx'} 它会转化为 file=xxx&filename=xxx的形式;
对于axios响应的信息,除了data属性是服务器返回的数据外,还有其它的信息,而我们项目中只需要响应主题信息,那么可以设置响应拦截器,直接获取响应的信息主体信息data,这样就不需要在获取响应数据时都去response.data了。
let axiosInstance = axios.create();
axiosInstance.defaults.baseURL = 'http://127.0.0.1:8000' // 路径配置
axiosInstance.defaults.headers['Content-Type'] = 'multipart/form-data'; // 请求头设置
axiosInstance.defaults.transformRequest = (data,headers) => {
const contentType = headers['Content-Type'];
if(contentType === 'application/x-www-form-urlencoded') return Qs.stringify(data);
return data;
}
axiosInstance.interceptors.response.use(response => {
return response.data;
},reason => {
return new Promise.reject(reason)
});
对于少量的接口需要使用其它请求头的,可以单独进行配置,代码如下:
axios.post('xxxx',fm,{
headers:{
'Content-Type':'x-www-form-urlencoded'
}
});
基于FormData进行单一文件上传
文件上传组件使用原生input标签,type为file类型,上传文件会触发change事件,
<input type="file" class="upload_inp">
<script>
;(() => {
let upload_inp = document.querySelector('.upload_inp');
upload_inp.addEventListener('change',function () {
console.log(upload_inp.files);
})
})()
</script>
我们获取该元素后,可以拿到该元素的files属性,它是一个类数组集合,输出内容如下:
可以通过upload_inp.files[0]拿到这个上传的文件的对象信息,其中:
+ name:文件名
+ size:文件大小,单位是字节
+ type:文件的MINE类型
1.限制上传文件的格式
方法1:使用正则
;(() => {
let upload_inp = document.querySelector('.upload_inp');
upload_inp.addEventListener('change',function () {
let file = upload_inp.files[0];
if(!file) return;
// 限制上传文件的格式
if(!/(PNG|JPG|JPEG)/i.test(file.type)) {
alert('上传的文件只能是PNG|JPG|JPEG格式的');
return;
}
})
})()
方法2:使用accept属性
<input type="file" class="upload_inp" accept=".png,.jpg,.jpeg">
这样选择文件时,就只会显示这三种类型的文件了
2.限制文件的上传大小
通过文件对象的file.size获取选择文件的大小,单位为字节B
// 限制文件的上传大小
if(file.size > 2 * 1024 * 1024) {
alert('上传的文件不能超过2MB');
return;
}
3.修改input标签的默认样式
input标签默认样式如果不是我们需要的效果,可以将其隐藏display:none,随后我们再创建一个按钮,在点击这个按钮时触发input的click方法;
<input type="file" class="upload_inp" accept=".png,.jpg,.jpeg">
<button class="select-file">选择文件</button>
......
select_file.addEventListener('click',function () {
upload_inp.click();
});