文件上传总结

文件上传总结

文件上传的方式有哪些(Flash已经淘汰,不再提及)

目前常用的只有2种

1. form上传

就是使用 inputFile 控件,form的enctype必须是 multipart/form-data

<form method="post" action="http://uploadUrl" enctype="multipart/form-data">
    <input name="file" type="file" accept="image/gif,image.jpg" />
    <input name="token" type="hidden" />
    <input type="submit" value="提交" /> 
</form>

1.1 多文件上传

inputFile 支持多文件上传, multipart属性 <input type="file" multipart />

1.2 无刷新上传

iframe + form 可以实现无刷新上传,将form的target设置为一个隐藏的iframe。

1.3 提交额外数据

form中可以使用input hidden提交隐藏字段,比如token等。

1.4 inputFile的美化

1.4.1 用透明度为0的 input file 覆盖美观的按钮
1.4.2 用label标签的for指向inputFile控件,美化label标签

2. ajax上传

使用的是XMLHttpRequest level2 + FormData, 或者是 Fetch + FormData

<form>
    <input type="file" id="f1" multiple/><br/><br/>
    <button type="button" id="btn-submit">上 传</button>
</form>
//XMLHttpRequest
function uploadFiles() {
    //获得文件列表,注意这里不是数组,而是对象
    var fileList = document.getElementById('f1').files;
    if(!fileList.length){
        alert('请选择文件');
        return;
    }
    var fd = new FormData();   //构造FormData对象
    fd.append('title', document.getElementById('title').value);

    //多文件上传需要遍历添加到 fromdata 对象
    for(var i =0;i<fileList.length;i++){
        fd.append('f1', fileList[i]);//支持多文件上传
    }

    var xhr = new XMLHttpRequest();   //创建对象
    xhr.open('POST', 'http://localhost:8100/', true);

    xhr.send(fd);//发送时  Content-Type默认就是: multipart/form-data; 
    xhr.onreadystatechange = function () {
        console.log('state change', xhr.readyState);
        if (this.readyState == 4 && this.status == 200) {
            var obj = JSON.parse(xhr.responseText);   //返回值
            console.log(obj);
            if(obj.fileUrl.length){
                alert('上传成功');
            }
        }
    }
}

//绑定提交事件
document.getElementById('btn-submit').addEventListener('click',uploadFiles);
//Fetch
fetch('http://uploadUrl', {
    method: 'POST',
    body: fd
})
.then(response => response.json())
.then(response =>{
    console.log(response);
    if (response.fileUrl.length) {
        alert('上传成功');
    }
} )
.catch(error => console.error('Error:', error));

2. 文件上传体验优化

2.1 上传进度

使用 xhr.onprogress 和 xhr.upload.onprogress

2.2 文件预览,主要是图片

img.src = window.URL.createObjectURL(file) //createObjectURL得到文件对象的blob url, 赋值给img的src即可

2.3 文件终止上传

xhr.abort()

2.4 文件拖曳上传

监听拖曳区域的drag释放事件,dragover,dragleave,drop事件,在drop事件中获取file对象,在通过ajax上传。

2.5 剪贴板上传

监听输入区域的paste事件,获取剪贴板数据,提取file数据,ajax上传成功后,将返回的图片地址赋值到一个image对象上,插入到光标处。
通常该输入区域,是一个 contentEditable 的 div,而不是textarea,因为其无法承载其他html元素

2.6 大文件上传

2.6.1 分片

大文件分片上传,分片传完后,再发送一个合并请求,告诉服务端上传文本,合并文件。服务端根据文件标识,合并文件。

文件标识,可以使用 文件名 和 序号。

文件分片的基本方法是,blob对象slice方法,blob.prototype.slice,File对象继承了Blob,文件也可以进行slice。

2.6.2 断点续传

对分片生成hash,将hash保存在服务端,下次上传从服务端获取hash信息,对比本地分片的hash,已经上传的部分进行
秒传,即只显示上传进度完成,跳过上传,只上传未上传的分片。

参考:https://juejin.im/post/5da14778f265da5bb628e590
         https://www.cnblogs.com/sunliyuan/p/5737928.html

原文地址:https://www.cnblogs.com/mengff/p/12927298.html