在前端開發(fā)中首昔,生成需要上傳文件的url的方式主要有兩種揭糕,分別是FileReader.readAsDataURL()和URL.createObjectURL()涛贯。
下面我將以input元素添加文件的方式演示這兩種方法的使用湘今。
FileReader.readAsDataURL()
readAsDataURL方法會讀取指定的 Blob 或 File 對象坦辟。讀取操作完成的時候择葡,觸發(fā) loadend 事件穷遂,同時result屬性將包含一個URL 格式的字符串(base64 編碼)以表示所讀取文件的內(nèi)容晾虑。
<!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指向產(chǎn)生的影響仙粱,比如vue的事件處理函數(shù)
let file=e.target.files[0];//只取第一個文件文件
// let file=this.files[0];
let fileReader=new FileReader();
fileReader.onload=function (e) {//讀取完畢時的回調(diào)
img.src=e.target.result;
img.style.display='block';
}
fileReader.readAsDataURL(file);//讀取file文件對象
})
}
</script>
</html>
這種方式生成的資源地址是很長的
URL.createObjectURL()
URL.createObjectURL()方法會創(chuàng)建一個 字符串,表示參數(shù)中給出的對象的URL彻舰。這個URL的生命周期和創(chuàng)建它的窗口中的 document綁定伐割。這個新的 URL 對象表示指定的 File 對象或 Blob 對象。
這種方式使用不當(dāng)會導(dǎo)致內(nèi)存泄漏刃唤,在每次調(diào)用 createObjectURL()方法時隔心,都會創(chuàng)建一個新的 URL 對象,即使你已經(jīng)用相同的對象作為參數(shù)創(chuàng)建過尚胞。當(dāng)不再需要這些 URL 對象時硬霍,每個對象必須通過調(diào)用URL.revokeObjectURL()方法來釋放。瀏覽器在 document 卸載的時候笼裳,會自動釋放它們须尚,但是為了獲得最佳性能和內(nèi)存使用狀況崖堤,你應(yīng)該在安全的時機(jī)主動釋放掉它們。
<!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);//釋放內(nèi)存
}
})
}
</script>
</html>
這種方式生成的資源地址就很短
添加文件的方式還有拖拽和粘貼
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();//阻止默認(rèn)事件
});
fileArea.addEventListener('dragover', function (e) {
e.stopPropagation();//阻止冒泡
e.preventDefault();//阻止默認(rèn)事件
});
fileArea.addEventListener('drop', function (e) {
e.stopPropagation();//阻止冒泡
e.preventDefault();//阻止默認(rèn)事件
let file = e.dataTransfer.files[0];//只取第一個文件測試
//在頁面上顯示圖片
fileShowToUrl(file);
});
//文件轉(zhuǎn)base64顯示
function fileShowToBase64(file) {
let fileReader = new FileReader();
fileReader.onload = function (e) {//讀取完畢時的回調(diào)
img.src = e.target.result;
img.style.display='block';
}
fileReader.readAsDataURL(file);//讀取file文件對象
}
//文件轉(zhuǎn)url顯示
function fileShowToUrl(file) {
let srcUrl = URL.createObjectURL(file);
img.src = srcUrl;
img.onload = function () {
img.style.display='block';
URL.revokeObjectURL(srcUrl);//釋放內(nèi)存
}
}
}
</script>
</html>
將需要添加的文件拖拽到對應(yīng)區(qū)域即可耐床。
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'){//簡單判斷一下數(shù)據(jù)類型
let file=e.clipboardData.files[0];//獲取第一個文件
fileShowToUrl(file);
}
})
//文件轉(zhuǎn)base64顯示
function fileShowToBase64(file) {
let fileReader = new FileReader();
fileReader.onload = function (e) {//讀取完畢時的回調(diào)
img.src = e.target.result;
img.style.display='block';
}
fileReader.readAsDataURL(file);//讀取file文件對象
}
//文件轉(zhuǎn)url顯示
function fileShowToUrl(file) {
let srcUrl = URL.createObjectURL(file);
img.src = srcUrl;
img.onload = function () {
img.style.display='block';
URL.revokeObjectURL(srcUrl);//釋放內(nèi)存
}
}
}
</script>
</html>
復(fù)制文件后在粘貼區(qū)域按ctrl+v即可撩轰。
參考文獻(xiàn):
https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
https://developer.mozilla.org/zh-CN/docs/Web/API/File