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

文件上传进度检测

    //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='删除';

        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调整样式
    

断点续传
    断点续传普通HTML做不到,通常需要客户端实现.

AJAX版本判断
    高级浏览器支持2.0.有ajax.upload的浏览器就是支持2.0

事件绑定取消默认事件
    直接事件绑定取消默认事件 需要return false;
    使用addEventListener 绑定的事件,取消默认事件需要使用ev.preventDefault();

关于base64
    服务器与浏览器之间传输数据的时候直接传输二进制,
    base64可以把二进制数据转换成字符串

Chrome模拟网速
    控制台 settings 中 Throttling 可以添加模拟网速,添加完成之后在NetWork中Online后选择;
Chrome查看loaclStorage、cookie在控制台Applocation中

你可能感兴趣的:(文件上传进度检测/拖拽上传的处理(读取文件内容))