美文网首页
文件上传进度检测/拖拽上传的处理(读取文件内容)

文件上传进度检测/拖拽上传的处理(读取文件内容)

作者: 子心_ | 来源:发表于2019-07-09 09:53 被阅读0次

    文件上传进度检测

        //AJAX2.0中AJAX对象有进度上传的监听事件(upload)
        //upload中有onprogress事件 
        //1.该事件必须放到AJAX创建后send()之前的位置,否则upload事件不会响应
        //2.使用此事件时,express必须使用server.use接收数据,设置跨域.
        //  原因是此时发送数据会产生两次请求POST与OPTIONS,使用USE才可以接收所有的请求
        ajax.upload.onprogress = function(ev){
            ev.loaded //表示完成了多少上传进度
            ev.total //表示总共有多少
            ev.loaded/ev.total  //=>得出0~1之间的数,代表进度
        }
        //注意事项
        ajax.onprogress 显示的是下载的进度
        ajax.upload.onprogress 显示的是上传的进度
    

    拖拽上传的处理(读取文件内容)

        //使用FileReader读取上传的文件
        let reader = new FileReader();
        //参数file是 拖动松手事件后返回ev..dataTransfer.files;参考2-6 119行
        readAsText(file)//读取文本文件
        readAsDataURL(file)//读取二进制的文件,以base64编码形式存储数据
        readAsBinaryString(file) //以字符串形式存储的二进制数据
        readAsArrayBuffer(file) //以二进制数据的形式存储数据,可以转换成Blob。
        reader.onload = function(){//通常把onload函数写在读取文件之前,防止文件读取太快,出现onload触发不了的BUG
            reader.result//获得上述四个方法读取文件内容的结果
        }
        //核心代码如下
        //拖住DIV的拖拽松手事件
        oBox.addEventListener('drop', (ev)=>{
        //循环长传的files操作
        Array.from(ev.dataTransfer.files).forEach(file=>{
            //判断如果该文件不是图片就取消本次操作
            if(!file.type.startsWith('image/')){
            return;
            }
            //创建文件读取对象
            let reader=new FileReader();
            //文件读取完毕事件
            reader.onload=function (){
            let oLi=document.createElement('li');
            oLi.file=file;//将file保存在li中,方便以后存库使用
            oLi.innerHTML='<img src="a.png" alt=""><a href="javascript:;" class="del_btn">删除</a>';
    
            let oImg=oLi.children[0];
            oImg.src=this.result;//图片地址指向文件读取结果,此处是base64
            //删除
            let oBtnDel=oLi.children[1];
            oBtnDel.onclick=function (){
                oUl.removeChild(oLi);
            };
    
            oUl.appendChild(oLi);
            };
            //文件读取,写在后面防止onload事件不被触发
            reader.readAsDataURL(file);
        });
        //阻止默认事件
        ev.preventDefault();
        }, false);
    
        //真的上传,点击上传后使用formdata上传
        let oBtnUpload=document.querySelector('#btn_upload');
        oBtnUpload.onclick=function (){
        let data=new FormData();//创建formdata对象
    
        Array.from(oUl.children).forEach(li=>{
            data.append('f1', li.file);//循环放入data中
        });
    
        //
        let oAjax=new XMLHttpRequest();//创建ajax
    
        //POST
        oAjax.open('POST', `http://localhost:8080/api`, true);
        oAjax.send(data);//发送数据
    
        oAjax.onreadystatechange=function (){
            if(oAjax.readyState==4){
            if(oAjax.status>=200 && oAjax.status<300 || oAjax.status==304){
                alert('成功');
            }else{
                alert('失败');
            }
            }
        };
        };
    
        //服务端代码如下 注释参考2-6;
        const express=require('express');     //主体
        const body=require('body-parser');    //接收普通POST数据
        const multer=require('multer');       //接收文件POST数据
        const mysql=require('mysql');         //数据库
        //连接数据库
        let db=mysql.createPool({host: 'localhost', port: 3309, user: 'root', password: '', database: '20180208'});
        //监听
        let server=express();
        server.listen(8080);
    
        //中间件
        server.use(body.urlencoded({extended: false}));
    
        let multerObj=multer({dest: './upload/'});
        server.use(multerObj.any());
    
        //处理请求
        server.use('/api', (req, res)=>{
            //处理跨域
            if(req.headers['origin']=='null' || req.headers['origin'].startsWith('http://localhost')){
                res.setHeader('Access-Control-Allow-Origin', '*');
            }
    
            let arr=[];
            req.files.forEach(file=>{
                arr.push(`('${file.originalname}', '${file.filename}', ${Math.floor(Date.now()/1000)})`);
            });
    
            let sql=`INSERT INTO image_table (originalname, filename, time) VALUES${arr.join(',')}`;
    
            db.query(sql, (err)=>{
                if(err){
                res.send('不OK');
                }else{
                res.send("OK");
                }
            });
        });
        server.use(express.static('./www/'));
    

    扩展

    服务器中有多个IP时,指定服务器监听IP
        server.listen中除了端口,还可以有参数指定IP,如果没有指定iP就是默认IP.
    
    meter标签(H5新增的进度条标签)//可以使用css调整样式
        <meter value='0~100进度值' min='0' max='100'>
    
    断点续传
        断点续传普通HTML做不到,通常需要客户端实现.
    
    AJAX版本判断
        高级浏览器支持2.0.有ajax.upload的浏览器就是支持2.0
    
    事件绑定取消默认事件
        直接事件绑定取消默认事件 需要return false;
        使用addEventListener 绑定的事件,取消默认事件需要使用ev.preventDefault();
    
    关于base64
        服务器与浏览器之间传输数据的时候直接传输二进制,
        base64可以把二进制数据转换成字符串
    
    Chrome模拟网速
        控制台 settings 中 Throttling 可以添加模拟网速,添加完成之后在NetWork中Online后选择;
    Chrome查看loaclStorage、cookie在控制台Applocation中

    相关文章

      网友评论

          本文标题:文件上传进度检测/拖拽上传的处理(读取文件内容)

          本文链接:https://www.haomeiwen.com/subject/yuutkctx.html