【原生js】前端文件上传解决方案总结

本文总结了前端文件上传的各种解决方案,包括基于FormData的单文件上传、base64编码、进度条显示、多文件上传、拖拽上传及大文件切片上传。详细讲解了限制文件格式和大小、修改input样式、axios二次封装、文件hash命名处理等关键点,覆盖了从基础到高级的全面技术点。
摘要由CSDN通过智能技术生成

目录

axios的二次封装

基于FormData进行单一文件上传

1.限制上传文件的格式

2.限制文件的上传大小

3.修改input标签的默认样式

4.文件上传服务器

基于base64文件上传

1.发送base64图像数据

2.客户端实现文件浏览

3.文件hash名字的编译处理

文件上传进度条显示

多文件上传

1.获取上传文件信息

2.显示待上传文件/删除待上传文件

3.多文件上传服务器

文件拖拽上传 

大文件切片上传和断点续传

1.获取文件已经上传的切片信息

2.文件的切片处理

3.上传切片

4.通知合并切片


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属性,它是一个类数组集合,输出内容如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546W5Ly0Xw==,size_20,color_FFFFFF,t_70,g_se,x_16

 可以通过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();
});

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值