当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 前端必知必会之文件上传攻略(一)

前端必知必会之文件上传攻略(一)

2019年10月20日  | 移动技术网IT编程  | 我要评论

文件上传原理

根据http协议的定义,完成请求消息体的封装和解析,将二进制内容保存至文件。

关键字:

multipart/form-data

含义:

multipart表示资源有多种元素组成,form-data使用post方式或html forms上传文件。

结构:

 

 

 

  • 请求头:表示本次请求要上传文件,其中boundary表示分隔符。
content-type: multipart/form-data; boundary=----webkitformboundary2ahjiirvmka4qn78
  • 消息体- form data 部分

content-disposition: form-data 为固定值,表示一个表单元素,name 表示表单元素的 名称,回车换行后面就是name的值,如果是上传文件就是文件的二进制内容。

content-type:表示当前的内容的 mime 类型(type/subtype)通用+子类,是图片还是文本还是二进制数据(text/.. application/... image/... video/...)。

解析:

客户端发送请求到服务器后,服务器拿到请求的消息体进行解析,解析出哪些是普通表单哪些是附件。一般不需要自行解析,有第三方库可用。

无刷新上传

关键字:

xmlhttprequest

xmlhttprequest2有了升级,首先就是可以读取和上传二进制数据,可以使用·formdata·对象管理表单数据。

示例:

<div>
        选择文件(可多选):
        <input type="file" id="f1" multiple/><br/><br/>
        <button type="button" id="btn-submit">上 传</button>
</div>
<script>
    function submitupload() {
        //获得文件列表,注意这里不是数组,而是对象
        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',submitupload);
</script>

实现进度条

借助xmlhttprequest2,实现单文件或多文件的上传进度条。

 

 

说明

  • 页面内增加一个用于显示进度的标签 div.progress
  • js 内处理增加进度处理的监听函数xhr.upload.onprogress
  • event.lengthcomputable这是一个状态,表示发送的长度有了变化,可计算
  • event.loaded表示发送了多少字节
  • event.total表示文件总大小
  • 根据event.loadedevent.total计算进度,渲染div.progress
 <div>

        选择文件(可多选):
            <input type="file" id="f1" multiple/><br/><br/>

            <div id="progress">
                <span class="red"></span>
            </div>

        <button type="button" id="btn-submit">上 传</button>

    </div>
<script>

    function submitupload() {
        var progressspan = document.getelementbyid('progress').firstelementchild;
        var filelist = document.getelementbyid('f1').files;
        progressspan.style.width='0';
        progressspan.classlist.remove('green');

        if(!filelist.length){
            alert('请选择文件');
            return;
        }

        var fd = new formdata();   //构造formdata对象
        fd.append('title', document.getelementbyid('title').value);

        for(var i =0;i<filelist.length;i++){
            fd.append('f1', filelist[i]);//支持多文件上传
        }

        var xhr = new xmlhttprequest();   //创建对象
        xhr.open('post', 'http://10.70.65.235:8100/', true);

        xhr.onreadystatechange = function () {
            console.log('state change', xhr.readystate);
            if (xhr.readystate == 4) {
                var obj = json.parse(xhr.responsetext);   //返回值
                console.log(obj);
                if(obj.fileurl.length){
                    //alert('上传成功');
                }
            }
        }

        xhr.onprogress=updateprogress;
        xhr.upload.onprogress = updateprogress;
        function updateprogress(event) {
            console.log(event);
            if (event.lengthcomputable) {
                var completedpercent = (event.loaded / event.total * 100).tofixed(2);
                progressspan.style.width= completedpercent+'%';
                progressspan.innerhtml=completedpercent+'%';
                if(completedpercent>90){//进度条变色
                    progressspan.classlist.add('green');
                }
                console.log('已上传',completedpercent);
            }
        }
        //注意 send 一定要写在最下面,否则 onprogress 只会执行最后一次 也就是100%的时候
        xhr.send(fd);//发送时  content-type默认就是: multipart/form-data; 
    }
    //绑定提交事件
    document.getelementbyid('btn-submit').addeventlistener('click',submitupload);


</script>

ps 特别提醒

xhr.upload.onprogress要写在xhr.send方法前面,否则event.lengthcomputable状态不会改变,只有在最后一次才能获得,也就是100%的时候.

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网