赞
踩
Blob 对象表示一个
不可变
、原始数据
的类文件对象
。它的数据可以按文本
或二进制
的格式进行读取,也可以转换成ReadableStream
来用于数据操作。 通常可以用于声音、视频等多媒体文件的存储;
new Blob(blobParts, options);
blobParts
:数组类型,可以存放任意个ArrayBuffer
、ArrayBufferView
、Blob
或DOMString
(会编码为utf-8);
options
:可选,可以设置blob的type
和endings
;
''
;\n
的字符串如何被写入。默认值_transparent_
保留不变,_native_
会改为对应宿主操作系统文件系统的换行符。DOMString 是一个UTF-16字符串。由于JavaScript已经使用了这样的字符串,所以DOMString直接映射到 一个String。
type
:返回blob的MIME类型
size
:blob的数据大小(字节)
返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。
Blob.slice([start[, end[, contentType]]])
// 返回一个能读取blob内容的 ReadableStream。
Blob.stream();
// 返回一个promise且包含blob所有内容的UTF-8格式的 USVString。
Blob.text()
// 返回一个promise且包含blob所有内容的二进制格式的 ArrayBuffer
Blob.arrayBuffer()
可以使用FileReader
对象
const reader = new FileReader();
reader.addEventListener('loaded', function() {
// reader.reasult 包含被转换为typedArray的Blob
});
reader.readAsArrayBuffer(blob);
可以使用Response
对象
const text = await (new Response(blob)).text()
通常情况下, File 对象是来自用户在一个
<input>
元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API
name
:文件名
size
:文件大小
lastModified
:文件最后修改时间对应时间戳
type
:MIME类型
webkitRelativePath
:返回file
相关的path和URL
slice
:继承了Blob的slice方法
<input>
元素
<input type="file" id="fileUploader" multiple accept="image">
<script>
const el = document.getElementById('fileUploader');
el.onchange = (e) => {
const files = e.target.files;
console.log({ files }, files[0])
}
</script>
<div id="fileUploader" ondrop="drop(e)" ondragover="allowDrop(e)" ></div> <script> function drop(e) { e.preventDefault(); const files = e.dataTransfer.files; console.log({ files }); console.log(files instanceof FileList); } function allowDrop(e) { e.preventDefault(); } </script>
数据缓冲区指的是内存中操作二进制数据的一片连续的存储区,相对于数组可以有效提高数据读取效率;
Buffer
是Node
提供的对象,可以通过Buffer创建存储二进制数据的缓冲区用于整合前端媒体文件数据 等;
一个Buffer类似于一个整数数组,但它对应于V8堆内存之外的一块原始内存
;
表示一段固定长度的连续的用于存储二进制数据的缓存区;对于高密度访问的数据(音视频数据等)读取效率更高,因为数据会提前写入到内存中;
属性——byteLength
,表示ArrayBuffer的大小
方法——slice(start, end)
,返回一个新的ArrayBuffer
ArrayBuffer未提供任何直接读写内存的方法,而ArrayBufferView是建立在ArrayBuffer上的视图,提供了处理二进制数据的基本单元,可以读取ArrayBuffer的内容;
TypedArrays
和DataView
是ArrayBufferView的实例
ileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
重要提示:FileReader 仅用于以安全的方式从用户(远程)系统读取文件内容 它不能用于从文件系统中按路径名简单地读取文件。要在 JavaScript 中按路径名读取文件,应使用标准 Ajax 解决方案进行服务器端文件读取,如果读取跨域,则使用 CORS 权限。
以下demo通过FileReader展示上传的图片
<!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title></title> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="" /> </head> <body> <input type="file" multiple id="myFile" /> <input type="file" multiple id="myFile2" /> <div id="previewer"></div> <script type="text/javascript"> if (window.FileReader) { var reader = new FileReader(); } else { console.log('你的浏览器不支持读取文件'); } var myFile = document.querySelector('#myFile'); myFile.onchange = function () { var file = myFile.files[0]; reader.readAsDataURL(file); reader.onload = function () { var data = reader.result; //base64形式的文件内容 console.log('data: ', data); const img = new Image(); img.src = data; document.querySelector('#previewer').appendChild(img); }; reader.onerror = function(){ console.log('读取失败'); console.log(reader.error); } }; // blobUrl(objectUrl) var myFile2 = document.querySelector('#myFile2'); myFile2.onchange = function (event) { const file = event.target.files[0]; const img = document.createElement('img'); img.src = window.URL.createObjectURL(file); // window.createObjectURL(file) || window.URL.createObjectURL(file) || window.webkitURL.createObjectURL(file) document.querySelector('#previewer').appendChild(img); } </script> </body> </html>
以下demo通过FileReader读取一个text文本文件内容:
<!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title></title> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="" /> </head> <body> <input type="file" multiple id="myFile" /> <input type="file" multiple id="myFile2" /> <input type="file" multiple id="textFile" /> <div id="previewer"></div> <script type="text/javascript"> // reader.readerAsText(file) const myFile3 = document.querySelector('#textFile'); const textReader = new FileReader(); myFile3.onchange = function (event) { const file = event.target.files[0]; textReader.onload = function () { const content = textReader.result; console.log('text content: ', content); } textReader.readAsText(file); } </script> </body> </html>
**BlobURL(ObjectURL)**是一种伪协议,只能由浏览器在内部生成,我们知道script/img/video/iframe等标签的src属性和background的url可以通过url和base64来显示,我们同样可以把blob或者file转换为url生成BlobURL来展示图像,BlobURL允许Blob和File对象用作图像,下载二进制数据链接等的URL源。
具体代码见上面demo
<!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title></title> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="" /> </head> <body> <input type="file" multiple id="myFile" /> <input type="file" multiple id="myFile2" /> <input type="file" multiple id="textFile" /> <button onclick="download()">下载</button> <div id="previewer"></div> <script type="text/javascript"> if (window.FileReader) { var reader = new FileReader(); } else { console.log('你的浏览器不支持读取文件'); } const getObjectURL = (file) => { let url; if (window.createObjectURL) { url = window.createObjectURL(file); } else if (window.URL) { url = window.URL.createObjectURL(file); } else if (window.webkitURL) { url = window.webkitURL.createObjectURL(file); } return url; }; var myFile = document.querySelector('#myFile'); myFile.onchange = function () { var file = myFile.files[0]; reader.readAsDataURL(file); reader.onload = function () { var data = reader.result; //base64形式的文件内容 console.log('data: ', data); const img = new Image(); img.src = data; document.querySelector('#previewer').appendChild(img); }; reader.onerror = function () { console.log('读取失败'); console.log(reader.error); } }; // blobUrl(objectUrl) var myFile2 = document.querySelector('#myFile2'); myFile2.onchange = function (event) { const file = event.target.files[0]; const img = document.createElement('img'); img.src = window.URL.createObjectURL(file); // window.createObjectURL(file) || window.URL.createObjectURL(file) || window.webkitURL.createObjectURL(file) document.querySelector('#previewer').appendChild(img); } // reader.readerAsText(file) const myFile3 = document.querySelector('#textFile'); const textReader = new FileReader(); myFile3.onchange = function (event) { const file = event.target.files[0]; textReader.onload = function () { const content = textReader.result; console.log('text content: ', content); } textReader.readAsText(file); } // file download function download() { const fileName = 'download.txt'; const myBlob = new Blob(['BlobURL download text file'], { type: 'text/plain' }); downloadFn(fileName, myBlob); } function downloadFn(fileName, blob) { const link = document.createElement('a'); link.href = getObjectURL(blob); link.download = fileName; link.click(); link.remove(); URL.revokeObjectURL(link.href); // 不再使用的BlobUrl后续会自动清除(关闭浏览器也会自动清除),但是最好使用URL.revokeObjectURL(url)手动清除它们 } </script> </body> </html>
dataURL允许内容的创建者将较小的文件嵌入到文档中。与常规的URL使用场合类似
data:[<mediatype>][;base64],data
Javascript中有两个函数负责编码和解码base64字符串,分别是atob和btoa。两者都只针对Data URL中的data进行处理。
这里主要用到canvas和imageData的转换
<!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title></title> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="" /> <style> .imgPreviewer { display: flex; } </style> </head> <body> <input type="file" multiple id="myFile" /> <input type="file" multiple id="myFile2" /> <input type="file" multiple id="textFile" /> <button onclick="download()">下载</button> <input type="file" id="grayImage" /> <div id="previewer"></div> <div class="imgPreviewer"> <canvas id="original"></canvas> <canvas id="gray"></canvas> </div> <script type="text/javascript"> if (window.FileReader) { var reader = new FileReader(); } else { console.log('你的浏览器不支持读取文件'); } const getObjectURL = (file) => { let url; if (window.createObjectURL) { url = window.createObjectURL(file); } else if (window.URL) { url = window.URL.createObjectURL(file); } else if (window.webkitURL) { url = window.webkitURL.createObjectURL(file); } return url; }; var myFile = document.querySelector('#myFile'); myFile.onchange = function () { var file = myFile.files[0]; reader.readAsDataURL(file); reader.onload = function () { var data = reader.result; //base64形式的文件内容 console.log('data: ', data); const img = new Image(); img.src = data; document.querySelector('#previewer').appendChild(img); }; reader.onerror = function () { console.log('读取失败'); console.log(reader.error); } }; // blobUrl(objectUrl) var myFile2 = document.querySelector('#myFile2'); myFile2.onchange = function (event) { const file = event.target.files[0]; const img = document.createElement('img'); img.src = window.URL.createObjectURL(file); // window.createObjectURL(file) || window.URL.createObjectURL(file) || window.webkitURL.createObjectURL(file) document.querySelector('#previewer').appendChild(img); } // reader.readerAsText(file) const myFile3 = document.querySelector('#textFile'); const textReader = new FileReader(); myFile3.onchange = function (event) { const file = event.target.files[0]; textReader.onload = function () { const content = textReader.result; console.log('text content: ', content); } textReader.readAsText(file); } // file download function download() { const fileName = 'download.txt'; const myBlob = new Blob(['BlobURL download text file'], { type: 'text/plain' }); downloadFn(fileName, myBlob); } function downloadFn(fileName, blob) { const link = document.createElement('a'); link.href = getObjectURL(blob); link.download = fileName; link.click(); link.remove(); URL.revokeObjectURL(link.href); // 不再使用的BlobUrl后续会自动清除(关闭浏览器也会自动清除),但是最好使用URL.revokeObjectURL(url)手动清除它们 } // 图像灰度化 const colorfulImageReader = document.querySelector('#grayImage'); const imgReader = new FileReader(); colorfulImageReader.onchange = (event) => { const file = event.target.files[0]; imgReader.readAsDataURL(file); imgReader.onload = () => { const result = imgReader.result; const img = document.createElement('img'); img.src = result; img.width = 300; img.height = 440; document.querySelector('#previewer').appendChild(img); console.log('images: ', img, img.width, img.height) img.onload = () => { const canvas = document.getElementById('original'); const context = canvas.getContext('2d'); canvas.width = img.width; canvas.height = img.height; context.drawImage(img, 0, 0, img.width, img.height); var imageData, data, i, len, average, red, green, blue; imgData = context.getImageData(0, 0, img.width, img.height); data = imgData.data; for (i = 0, len = data.length; i < len; i += 4) { red = data[i]; green = data[i + 1]; blue = data[i + 2]; // alpha = data[i + 3]; average = Math.floor((red + green + blue) / 3); data[i] = average; data[i + 1] = average; data[i + 2] = average; } imgData.data = data; const myCanvas = document.getElementById('gray'); myCanvas.width = img.width; myCanvas.height = img.height; const myContext = myCanvas.getContext('2d'); myContext.putImageData(imgData, 0, 0, 0, 0, img.width, img.height); } } } </script> </body> </html>
A Number between 0 and 1 indicating the image quality to be used when creating images using file formats that support lossy compression (such as image/jpeg or image/webp). A user agent will use its default quality value if this option is not specified, or if the number is outside the allowed range.
toDataURL(type, encoderOptions)第二个参数可以用于控制图片质量,可以用此参数实现图片压缩
// compress.js const MAX_WIDTH = 800; // 图片最大宽度 function compress(base64, quality, mimeType) { let canvas = document.createElement('canvas'); let img = document.createElement('img'); img.crossOrigin = 'anonymous'; return new Promise((resolve, reject) => { img.src = base64; img.onload = () => { let targetWidth, targetHeight; if (img.width > MAX_WIDTH) { targetWidth = MAX_WIDTH; targetHeight = (img.height * MAX_WIDTH) / img.width; } else { targetWidth = img.width; targetHeight = img.height; } canvas.width = targetWidth; canvas.height = targetHeight; let ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, targetWidth, targetHeight); // 清除画布 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 通过toDataURL压缩后的base64 let imageData = canvas.toDataURL(mimeType, quality / 100); resolve(imageData); }; }); }
<body> <input type="file" accept="image/*" onchange="loadFile(event)" /> <script src="./compress.js"></script> <script> function dataUrlToBlob(base64) { var arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); } function uploadFile(url, blob) { let formData = new FormData(); let request = new XMLHttpRequest(); // 封装到FormData中进行文件的上传 formData.append('image', blob); request.open('POST', url, true); request.send(formData); } const loadFile = function (event) { const reader = new FileReader(); reader.onload = async function () { let compressedDataURL = await compress(reader.result, 90, 'image/jpeg'); // 压缩后将base64转为Blob 对象减少传输数据量 let compressedImageBlob = dataUrlToBlob(compressedDataURL); uploadFile('https://httpbin.org/post', compressedImageBlob); }; // 获取用户选取的图片文件,通过FileReader转化成base64 reader.readAsDataURL(event.target.files[0]); }; </script> </body>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。