文件上传进度检测
//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中
网友评论