前言
本文记录 JavaScript 中的文件流,持续更新中……
使用Blob下载文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| function download() { axios({ url: `http://localhost:2000/download`, method: 'GET', responseType: 'blob', }).then(result => { const blob = new Blob([result.data], { type: "image/jpeg" }) const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.download = `1.png`; a.href = url; a.click()
}).catch((err) => { console.log(err); }) }
export const downloadFile = async (params, fileName) => { const results = await download(params); const a = document.createElement("a"); a.download = fileName + ".xlsx"; a.href = window.URL.createObjectURL(results); a.style.display = "none"; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(a.href); document.body.removeChild(a); };
|
File
参考:MDN文档 重学JS | 玩转File API (掘金)
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件,支持读取 File 或 Blob 对象指定要读取的文件或数据,是一种异步文件读取机制。
FileReader 常用 api
方法
- readAsText(file,encoding):以纯文本的形式读取文件
- readAsDataURL(file):读取文件并将文件以数据URI的格式保存到result
- readAsBinaryString(file):读取文件并将一个字符串保存在result属性中,字符串中的每个字符表示一字节
- readAsArrayBuffer(file):读取文件并将一个包含文件内容的ArrayBuffer保存到result属性中
事件
- progress:表示又读取了数据,50ms左右触发一次
- error:发生了错误触发
- load:已经读完了整个文件触发
- abort:中断读取过程
- loadend:整个过程结束,load、error、abort事件触发后触发的事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| <input type="file"> <script> let fileReader = new FileReader() let file = document.querySelector('input') file.onchange = function() { let fileType = this.files[0]; fileReader.readAsDataURL(this.files[0]); fileReader.onload = (e) => { const result = e.target.result console.log(result) } }
</script>
// ---------------------- // 其他补充 <body> <input type='file' onchange="fileChange(this)" /> <div id='output' /> <script> function fileChange(target){ var file = target.files[0], output = document.getElementById('output'), type = '', reader = new FileReader(); if(/image/.test(file.type)){ type = 'image' reader.readerAsDataURL(file) }else{ type = 'text' reader.readAsText(file) } reader.onprogress = function(e){ if(e.lengthComputable){ console.log('当前读取进度为':e.loaded+'/'+e.total) } } reader.onerror = function(){ var errCode = reader.error.code } reader.onload = function(){ var html = type==='image'?`<img src='${reader.result}'>`:reader.result output.innerHtml = html } reader.onloadend = function(){} } </script> </body>
|
URL.createObjectURL()方法
接收一个参数表示指定的 File 对象或 Blob 对象。
1 2 3 4 5 6 7 8
| var file = document.getElementById("inp"); file.onchange = function () { let url = window.URL.createObjectURL(this.files[0]) console.log(url) }
window.URL.revokeObjectURL(url)
|
文件上传
单张图片上传
1 2 3 4 5 6
|
let formData = new FormData(); formData.append('file', file);
|
一次多张图片上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| <body> <section class="uploadBox clearfix"> <div class="card button"> <input type="file" id="uploadInp" accept="image/*" multiple> </div>
</section>
<script> (function () { function postRequest(url, data, config) { config = config || {}; return axios.post(`xxx${url}`, data, config).then(response => { return response.data; }); }
function fileReader(file) { return new Promise(resolve => { let reader = new FileReader; reader.readAsDataURL(file); reader.onload = ev => { resolve(ev.target.result); }; }); } let uploadBox = document.querySelector('.uploadBox'), button = uploadBox.querySelector('.button'), uploadInp = uploadBox.querySelector('#uploadInp'); button.onclick = function () { uploadInp.click(); }; uploadInp.onchange = async function () { let self = this, files = Array.from(self.files); if (files.length === 0) return;
let uploadList = []; files.forEach((file, index) => { uploadList[index] = { file: file, base64: null, card: null }; });
let base64List = await Promise.all(files.map(file => fileReader(file))), frag = document.createDocumentFragment(); base64List.forEach((base64, index) => { let card = document.createElement('div'); card.className = 'card'; card.innerHTML = ` <img src="${base64}" alt=""> <div class="progress"> <div class="line"></div> </div> <div class="mark"></div> `; frag.appendChild(card); uploadList[index].base64 = base64; uploadList[index].card = card; }); uploadBox.appendChild(frag);
uploadList.forEach(async item => { let { file, base64, card } = item;
let data = { chunk: encodeURIComponent(base64), filename: file.name }, config = { headers: { "Content-Type": "application/x-www-form-urlencoded" }, onUploadProgress(ev) { let ratio = ev.loaded / ev.total * 100 + '%'; card.querySelector('.line').style.width = ratio; } }; let response = await postRequest('/upload', Qs.stringify(data), config); if (response.code === 0) { await delay(); let progress = card.querySelector('.progress'), mark = card.querySelector('.mark'); card.removeChild(progress); card.removeChild(mark); } }); }; })(); </script> </body>
|
拖拽上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
let uploadBox = document.querySelector('.uploadBox'); uploadBox.ondrop = function (ev) { ev.preventDefault(); console.log(ev.dataTransfer.files[0]); };
uploadBox.ondragenter = function () { uploadBox.innerHTML = '请释放鼠标'; }; let num = 0 uploadBox.ondragover = function () { uploadBox.innerHTML = '一直触发hover' + ++num; }; uploadBox.ondragleave = function () { uploadBox.innerHTML = '请将文件拖拽到此区域'; };
|
补充
参考:掘金
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
let str = 'abc/:' encodeURI(str); decodeURI() encodeURIComponent(str); decodeURIComponent()
let file = new File(array, name,options)
|