在Web开发过程中,当项目做得越来越大时,文件上传功能也会被使用得非常多,之前项目经理反馈一个问题,就是当点击[选择上传文件]按扭时,弹出文件浏览框总是很慢,点击上传按扭后,要很久文件选择窗口才能弹出来,经过一翻折腾,后来发现是因为input file类型的标签中 没有限制指定可上传的文件类型 accept=“*” (默认全部类型)。
所以它会检索全部类型,从而导致在弹出文件选择窗口时慢的问题。
然而,在HTML5中使用 input file控件 选择上传文件的时候,根据需要可限制指定的文件类型(默认任意类型 )。在 input type=“file” 加上 accept="指定要上传的文件类型"即可。
更多MIME类型:
参见1:https://www.w3school.com.cn/media/media_mimeref.asp
参见2:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types
例如:
<input type="file" id="oFile" name="myFiles" accept=".doc, .docx, .xls, .txt" onchange="upFile(event)" />
accept属性常见配置:(如果不加accept属性,则上传任意类型的文件[默认])
accept=".doc, .docx, .xls, .txt" // 只能上传word, exls, .txt文件
accept=".rar, .zip" // 只能上传压缩文件
accept=".mp3" // 只能上传mp3文件
accept=".mp4, .avi, .swf, .mpeg" // 只能上传视频文件
accept=".jpg, .jpeg .png, .gif, .bmp" // 只能上传指定的这些图片文件
accept="image/*" // image表示图片,*表示所有支持的格式, video/* video表示视频,*表示所有支持的格式
注意:如想要真正的限制用户只能上传某些类型的文件,用accept属性来做限制是没用的!!
因为:用户可以随意的修改文件的后缀名(扩展名)
所以:想要真正的限制用户只能上传某些类型的文件,
HTML5中的input type="file"在选择上传文件的时候,根据需要可限制选择 1个 或 多个 文件。在 input type=“file” 加上 multiple 属性 即可!
例如:
<input type="file" id="oFile" name="myFiles" multiple onchange="upFile(event)" />
1、上传时可以同进选多个文件( multiple 属性 ):
想要在上传时可以同进选多个文件,只需要在 input标签中加上 multiple 属性 就可以多选啦!多选的方式:可按住鼠标左键拖动进行多选,或按下键盘上的Ctrl键,或 Shitf键 再鼠标左键点选,或 Ctrl + A 全选。
注意: 默认情况下一般都没加multiple 属性,所以只能选择1个文件
最后:如果以上两种情况都要用到时,就同时加上 multiple属性 和 accept="指定要上传的文件类型"属性即可!
例如:
<input type="file" id="oFile" name="myFiles" multiple accept=".jpg, .jpeg .png, .gif, .bmp" onchange="upFile(event)" />
2、在JS中获取上传文件的相关属性
一般在文件上传,经常会做一些配置和限制如,文件的类型、大小等,可以在上传事件中获取到上传文件的相关属性。
function upFile(event) {
const file = event.target.files[0] || event.dataTransfer.files[0] || this.file.files[0];
console.dir(file); // 文件对象
console.log(file.name); // 文件名称
console.log(file.type); // 文件类型
console.log(file.size); // 文件大小
// 对文件类型做简单限制:如:只允许上传 jpg png gif 这3种格式
if(!file.type && /\.(?:jpg|png|gif)$/.test(file.name)) ){
alert('对不起:上传的图片格式只能是:jpg, png, gif');
return false;
}
// 使用FormData方式上传,并设置相应的参数
const fData = new FormData();
fData.set("myFiles", file); // 设置上传属性
fData.set("myxxx", 'abcdef'); // 设置自定义上传参数
fData.append("name", file.name); // 添加上传信息
fData.append("type", file.type); // 添加上传信息
fData.append("size", file.size); // 添加上传信息
fData.append("id", 666); // 添加上传信息
}
3、上传图片文件时即时预览图片:
当然,最好的预览是在图片真正的上传成功后,根据后端API返回的图片文件URL是最为稳妥的,但是由于文件上传会有一定延时性等原因,所以为了提高用户体验,可以在用户点击上传的同时,先看到图片的预览效果,等到真正的上传成功后在无感的替换掉就OK啦。
function upFile(event) {
const file = event.target.files[0] || event.dataTransfer.files[0] || this.file.files[0];
// 图片预览1
const createObjectURL = window.createObjectURL || window.URL.createObjectURL || window.webkitURL.createObjectUR;
console.log(createObjectURL(file)));
// 图片预览2
const fr = new FileReader();
fr.readAsDataURL(file); // Base64 8Bit字节码
// fr.readAsBinaryString(file); // Binary 原始二进制
// fr.readAsArrayBuffer(file); // ArrayBuffer 文件流
fr.onload = function(res) {
console.log(this.result);
console.log(res.target.result);
console.log(res.srcElement.result);
};
// 注意:当第二次再次选择之前的那个文件后,onchange事件不触发,所以要清空一下value
if (event.target.outerHTML) {
event.target.outerHTML = event.target.outerHTML;
} else {
event.target.value = '';
};
}
4、上传时如何判断文件的大小:
上传时在JS中通过event对象下的target属性,就可以获取当前上传文件的大小啦!
但是:由于在上传时文件的单位是以字节(Byte)为单位,所以需要做一下转换。
function upFile(event) {
const file = event.target.files[0] || event.dataTransfer.files[0] || this.file.files[0];
console.log((file.size / 1024 ).toFixed(2)); // KB;
console.log((file.size / 1024 / 1024).toFixed(2); // MB;
console.log((file.size / 1024 / 1024 / 1024).toFixed(2)); // GB;
// 限制文件大小在500KB以内
if(file.size / 1024 > 500){
alert('对不起:上传的文件不能大于500KB');
return false;
}
// 限制文件大小在2MB以内
if(file.size / 1024 / 1024 > 2){
alert('对不起:上传的文件不能大于2MB');
return false;
}
// 还可以用乘法来计算上传文件大小
1KB = 1 * 1024;
1MB = 1 * 1024 * 1024;
1GB = 1 * 1024 * 1024 * 1024;
// 限制文件大小在3MB以内
if(file.size > 3 * 1024 * 1024){
alert('对不起:上传的文件不能大于3MB');
return false;
}
/* 其他: 文件上传进度 的 百分比计算公式:
event.loaded 文件已上传的大小
event.total 文件的总大小
progress = 100 * event.loaded / event.total;
*/
progress = (100 * event.loaded / event.total).toFixed(2); // 保留2位小数
}
在计算机信息技术应用中,信息存储量是度量存储器存放程序和数据的数量。其主要度量单位是字节(Byte),
1个字节(Byte) 等于8位(bit)二进制。
位(bit,Binary Digits):是存放一位二进制数,即0或1,为最小的存储单位,8个二进制位为1个字节单位。
1个英文字母(不分大小写)占1个字节的空间,英文标点占1个字节。
1个中文汉字占2个字节的空间,中文标点占2个字节。
单 位 | 说 明 | 换 算 |
---|---|---|
Bit | (Bit,位) | 最小存储单位(二进制数,即 0 或 1) |
Byte | (Byte,字节) | 等于 8位(bit) |
KB | ( Kilobyte,千字节) | 1KB( Kilobyte,千字节) = 1024B |
MB | ( Megabyte,兆字节) | 1MB( Megabyte,兆字节) = 1024KB |
GB | ( Gigabyte,吉字节,千兆) | 1GB( Gigabyte,吉字节,千兆) = 1024MB |
TB | ( Trillionbyte,万亿字节,太字节) | 1TB( Trillionbyte,万亿字节,太字节) = 1024GB |
PB | ( Petabyte,千万亿字节,拍字节) | 1PB( Petabyte,千万亿字节,拍字节) = 1024TB |
EB | ( Exabyte,百亿亿字节,艾字节) | 1EB( Exabyte,百亿亿字节,艾字节) = 1024PB |
ZB | (Zettabyte,十万亿亿字节,泽字节) | 1ZB(Zettabyte,十万亿亿字节,泽字节) = 1024EB |
YB | ( Yottabyte,一亿亿亿字节,尧字节) | 1YB( Yottabyte,一亿亿亿字节,尧字节) = 1024ZB |
BB | ( Brontobyte,千亿亿亿字节) | 1BB( Brontobyte,千亿亿亿字节) = 1024YB |