Skip to content

Blob 快速上手

TIP

好久没输出内容了- -

Blob

Blob表示二进制数据对象,在Javascript中的Blob通常作为一个不可变的类似文件对象的原始数据

Blob由MIME类型和BlobParts数组组成,BlobParts可以为DOM string/ArrayBuffer/Blob内容

var blob = new Blob(BlobParts,{type,endings})

字符串创建

javascript
let myBlobParts = ['<html><h2>Hello Semlinker</h2></html>']; // an array consisting of a single DOMString
let myBlob = new Blob(myBlobParts, {type : 'text/html', endings: "transparent"}); // the blob

console.log(myBlob.size + " bytes size"); // Output: 37 bytes size
console.log(myBlob.type + " is the type"); // Output: text/html is the type

类型数组和字符串拼接

javascript
let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
let blob = new Blob([hello, ' ', 'semlinker'], {type: 'text/plain'}); // 组成 hello semlinker

Blob属性

  • type 只读,表面该Blob的MIME类型
  • size 只读,Blob大小

Blob方法

注意Blob是不可变

  • slice() 返回范围内的数据的新Blob对象
  • stream() 返回一个能读取这个Blob对象的可读流
  • text() 返回一个Promise包含UTF8格式的所有内容
  • arrayBuffer() 返回一个Promise包含二进制的ArrayBuffer内容

场景

分片上传

javascript
const file = new File(["a".repeat(1000000)], "test.txt");

const chunkSize = 40000;
const url = "https://httpbin.org/post";

async function chunkedUpload() {
  for (let start = 0; start < file.size; start += chunkSize) {
      const chunk = file.slice(start, start + chunkSize + 1);
      const fd = new FormData();
      fd.append("data", chunk);

      await fetch(url, { method: "post", body: fd }).then((res) =>
        res.text()
      );
  }
}

请求

javascript
const downloadBlob = (url, callback) => {
 const xhr = new XMLHttpRequest()
 xhr.open('GET', url)
 xhr.responseType = 'blob'
 xhr.onload = () => {
    callback(xhr.response)
 }
 xhr.send(null)
}
// axios
axios({
  url,
  responseType:'blob'
}).then(res=> console.log(res))

//fetch
const myImage = document.querySelector('img');
const myRequest = new Request('flowers.jpg');

fetch(myRequest)
  .then(function(response) {
    return response.blob();
  })
 .then(function(myBlob) {
   let objectURL = URL.createObjectURL(myBlob);
   myImage.src = objectURL;
});

下载

javascript
const download = (fileName, blob) => {
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = fileName;
  link.click();
  link.remove();
  URL.revokeObjectURL(link.href);
};

const downloadBtn = document.querySelector("#downloadBtn");
downloadBtn.addEventListener("click", (event) => {
  const fileName = "blob.txt";
  const myBlob = new Blob(["一文彻底掌握 Blob Web API"], { type: "text/plain" });
  download(fileName, myBlob);
});

预览

html
<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>

<script>
  const loadFile = function(event) {
    const reader = new FileReader();
    reader.onload = function(){
      const output = document.querySelector('output');
      output.src = reader.result;
    };
    reader.readAsDataURL(event.target.files[0]);
  };
</script>

PDF

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>客户端生成 PDF 示例</title>
  </head>
  <body>
    <h3>客户端生成 PDF 示例</h3>
    <script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
    <script>
      (function generatePdf() {
        const doc = new jsPDF();
        let imgData = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/...'

        doc.text("jsPDF!", 66, 88); // 指定坐标添加文本
        doc.addImage(imgData, 'JPEG', 15, 40, 180, 160) // 指定坐标添加图片

        const blob = new Blob([doc.output()], { type: "application/pdf" });
        blob.text().then((blobAsText) => {
          console.log(blobAsText);
        });
      })();
    </script>
  </body>
</html>

ArrayBuffer转换

javascript
const fr = new FileReader()
fr.readAsArrayBuffer() // 转换blob为 arraybuffer

new Blob([new Uint8Array(data)]) //arraybuffer 转换blob