在前端开发中,生成需要上传文件的url的方式主要有两种,分别是FileReader.readAsDataURL()和URL.createObjectURL()。
下面我将以input元素添加文件的方式演示这两种方法的使用。
FileReader.readAsDataURL()
readAsDataURL方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,触发 loadend 事件,同时result属性将包含一个URL 格式的字符串(base64 编码)以表示所读取文件的内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<input id="input" type="file">
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
window.onload=function () {
let input=document.getElementById('input');
let img=document.getElementById('img');
input.addEventListener('change',function (e) {
//以下两种写法都能获取到file对象,第一种可以避免this指向产生的影响,比如vue的事件处理函数
let file=e.target.files[0];//只取第一个文件文件
// let file=this.files[0];
let fileReader=new FileReader();
fileReader.onload=function (e) {//读取完毕时的回调
img.src=e.target.result;
img.style.display='block';
}
fileReader.readAsDataURL(file);//读取file文件对象
})
}
</script>
</html>
这种方式生成的资源地址是很长的
FileReader.png
URL.createObjectURL()
URL.createObjectURL()方法会创建一个 字符串,表示参数中给出的对象的URL。这个URL的生命周期和创建它的窗口中的 document绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。
这种方式使用不当会导致内存泄漏,在每次调用 createObjectURL()方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用URL.revokeObjectURL()方法来释放。浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<input id="input" type="file">
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
window.onload = function () {
let input = document.getElementById('input');
let img=document.getElementById('img');
input.addEventListener('change', function (e) {
//以下两种写法都能获取到file对象
let file = this.files[0];//只取第一个文件文件
// let file=e.target.files[0];
let srcUrl=URL.createObjectURL(file);
img.src=srcUrl;
img.onload=function () {
img.style.display='block';
URL.revokeObjectURL(srcUrl);//释放内存
}
})
}
</script>
</html>
这种方式生成的资源地址就很短
createObjectURL.png
添加文件的方式还有拖拽和粘贴
1.拖拽添加文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件拖拽</title>
</head>
<body>
<div id="file_area" style="position:absolute;width: 200px;height: 200px;background-color: #61b0d3">拖拽到此添加文件</div>
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
window.onload = function () {
let fileArea = document.getElementById('file_area');
let img=document.getElementById('img');
fileArea.addEventListener('dragenter', function (e) {
e.stopPropagation();//阻止冒泡
e.preventDefault();//阻止默认事件
});
fileArea.addEventListener('dragover', function (e) {
e.stopPropagation();//阻止冒泡
e.preventDefault();//阻止默认事件
});
fileArea.addEventListener('drop', function (e) {
e.stopPropagation();//阻止冒泡
e.preventDefault();//阻止默认事件
let file = e.dataTransfer.files[0];//只取第一个文件测试
//在页面上显示图片
fileShowToUrl(file);
});
//文件转base64显示
function fileShowToBase64(file) {
let fileReader = new FileReader();
fileReader.onload = function (e) {//读取完毕时的回调
img.src = e.target.result;
img.style.display='block';
}
fileReader.readAsDataURL(file);//读取file文件对象
}
//文件转url显示
function fileShowToUrl(file) {
let srcUrl = URL.createObjectURL(file);
img.src = srcUrl;
img.onload = function () {
img.style.display='block';
URL.revokeObjectURL(srcUrl);//释放内存
}
}
}
</script>
</html>
将需要添加的文件拖拽到对应区域即可。
QQ录屏20220929095012 00_00_00-00_00_30.gif
2.粘贴文件
粘贴文件存在兼容性问题,不建议使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>粘贴文件显示</title>
</head>
<body>
<div id="clipboard" style="position: absolute;width: 300px;height: 300px;background-color: #bbffaa">粘贴板</div>
<img src="" alt="添加的图片" id="img" style="position: absolute;left: 300px;height: 300px;display: none">
</body>
<script>
window.onload=function () {
let clipboard=document.getElementById('clipboard');
let img=document.getElementById('img');
clipboard.addEventListener('paste',function (e) {
console.log('paste');
if(!(e.clipboardData&&e.clipboardData.items)){
return;
}
if(e.clipboardData.items[0]&&e.clipboardData.items[0].kind==='file'){//简单判断一下数据类型
let file=e.clipboardData.files[0];//获取第一个文件
fileShowToUrl(file);
}
})
//文件转base64显示
function fileShowToBase64(file) {
let fileReader = new FileReader();
fileReader.onload = function (e) {//读取完毕时的回调
img.src = e.target.result;
img.style.display='block';
}
fileReader.readAsDataURL(file);//读取file文件对象
}
//文件转url显示
function fileShowToUrl(file) {
let srcUrl = URL.createObjectURL(file);
img.src = srcUrl;
img.onload = function () {
img.style.display='block';
URL.revokeObjectURL(srcUrl);//释放内存
}
}
}
</script>
</html>
复制文件后在粘贴区域按ctrl+v即可。
QQ录屏20220929095927 00_00_00-00_00_30.gif
参考文献:
https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
https://developer.mozilla.org/zh-CN/docs/Web/API/File