การสร้าง BLOB จากสตริง Base64 ใน JavaScript


447

ฉันมีข้อมูลเลขฐานสองที่เข้ารหัส Base64 ในสตริง:

const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

ฉันต้องการสร้างblob:URL ที่มีข้อมูลนี้และแสดงต่อผู้ใช้:

const blob = new Blob(????, {type: contentType});
const blobUrl = URL.createObjectURL(blob);

window.location = blobUrl;

ฉันไม่สามารถหาวิธีสร้าง BLOB ได้

ในบางกรณีฉันสามารถหลีกเลี่ยงสิ่งนี้ได้โดยใช้data:URL แทน:

const dataUrl = `data:${contentType};base64,${b64Data}`;

window.location = dataUrl;

อย่างไรก็ตามในกรณีส่วนใหญ่data:URL นั้นมีขนาดใหญ่มาก


ฉันจะถอดรหัสสตริง Base64 เป็นวัตถุ BLOB ใน JavaScript ได้อย่างไร

คำตอบ:


790

atobฟังก์ชั่นจะถอดรหัสสตริง Base64 เข้ารหัสเป็นสตริงใหม่ที่มีตัวอักษรสำหรับไบต์ของข้อมูลไบนารีแต่ละ

const byteCharacters = atob(b64Data);

รหัสจุดของอักขระแต่ละตัว (charCode) จะเป็นค่าของไบต์ เราสามารถสร้างอาร์เรย์ของค่าไบต์โดยใช้สิ่งนี้โดยใช้.charCodeAtวิธีการสำหรับตัวละครแต่ละตัวในสตริง

const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i);
}

คุณสามารถแปลงอาร์เรย์ของค่าไบต์นี้เป็นอาร์เรย์ไบต์ที่พิมพ์จริงโดยส่งผ่านไปยังตัวUint8Arrayสร้าง

const byteArray = new Uint8Array(byteNumbers);

ในทางกลับกันสามารถแปลงเป็น BLOB โดยห่อในอาร์เรย์และส่งผ่านไปยังตัวBlobสร้าง

const blob = new Blob([byteArray], {type: contentType});

รหัสดังกล่าวใช้งานได้ อย่างไรก็ตามประสิทธิภาพสามารถปรับปรุงได้เพียงเล็กน้อยโดยการประมวลผลbyteCharactersชิ้นเล็ก ๆ มากกว่าในคราวเดียว ในการทดสอบคร่าวๆของฉัน 512 ไบต์ดูเหมือนว่าจะมีขนาดที่ดี สิ่งนี้ทำให้เรามีฟังก์ชั่นดังต่อไปนี้

const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, {type: contentType});
  return blob;
}
const blob = b64toBlob(b64Data, contentType);
const blobUrl = URL.createObjectURL(blob);

window.location = blobUrl;

ตัวอย่างเต็มรูปแบบ:


6
สวัสดีเจเรมี เรามีรหัสนี้ในเว็บแอปพลิเคชันของเราและมันไม่ได้ทำให้เกิดปัญหาใด ๆ จนกว่าไฟล์ที่ดาวน์โหลดจะมีขนาดใหญ่ขึ้น ดังนั้นจึงทำให้แฮงค์และขัดข้องในเซิร์ฟเวอร์ที่ใช้งานจริงเมื่อผู้ใช้ใช้ Chrome หรือ IE เพื่อดาวน์โหลดไฟล์ที่มีขนาดใหญ่กว่า 100mb เราพบว่าในบรรทัดต่อไปนี้ของ IE กำลังเพิ่มข้อยกเว้นหน่วยความจำ "var byteNumbers = new Array (slice.length)" อย่างไรก็ตามในโครเมี่ยมมันเป็นห่วงทำให้เกิดปัญหาเดียวกัน เราไม่พบวิธีแก้ไขปัญหาที่เหมาะสมจากนั้นเราย้ายไปดาวน์โหลดไฟล์โดยตรงโดยใช้ window.open คุณสามารถให้ความช่วยเหลือที่นี่ได้ไหม?
Akshay Raut

นั่นคือวิธีการใด ๆ ในการแปลงไฟล์วิดีโอเป็น base64 แบบเนทีฟ ฉันจัดการด้วยไฟล์ภาพ แต่ไม่พบวิธีแก้ปัญหาสำหรับวิดีโอเช่นเดียวกัน ลิงค์จะเป็นประโยชน์หรือแก้ปัญหาด้วย
Diksha235

ดังนั้นจึงไม่มีปัญหาการจัดเก็บ 0 ในสตริงที่ส่งกลับโดย atob ()?
wcochran

สิ่งนี้ไม่ได้ผลสำหรับฉันสำหรับ blobs บางอย่างบน Chrome และ Firefox แต่ทำงานบนขอบ: /
Gragas ที่เข้ามา

ทำงานให้ฉัน มันพ่นข้อผิดพลาด ** JSON แจง: โทเค็นที่ไม่รู้จัก '<' ** ฉันตรวจสอบสตริงเบส 64 โดยใส่เบราว์เซอร์ที่มันกำลังสร้างภาพ ต้องการความช่วยเหลือ.
Aman Deep

273

นี่เป็นวิธีที่น้อยที่สุดโดยไม่ต้องพึ่งพาหรือไลบรารีใด ๆ
มันต้องการ API การดึงข้อมูลใหม่ ( ฉันสามารถใช้มันได้หรือไม่ )

var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="

fetch(url)
.then(res => res.blob())
.then(console.log)

ด้วยวิธีนี้คุณสามารถรับ ReadableStream, ArrayBuffer, text และ JSON ได้อย่างง่ายดาย

ในฐานะที่เป็นฟังก์ชั่น:

const b64toBlob = (base64, type = 'application/octet-stream') => 
  fetch(`data:${type};base64,${base64}`).then(res => res.blob())

ฉันทำการทดสอบประสิทธิภาพอย่างง่าย ๆ ไปยังรุ่นการซิงค์ ES6 ของ Jeremy
เวอร์ชันการซิงค์จะบล็อก UI ชั่วขณะหนึ่ง การเปิด devtool ไว้จะทำให้ประสิทธิภาพการดึงข้อมูลช้าลง


1
สิ่งนี้จะยังใช้งานได้หรือไม่ถ้าขนาดของสตริงที่เข้ารหัส base64 มีขนาดใหญ่สมมติว่ามีขนาดใหญ่กว่า 665536 ตัวอักษรซึ่งเป็นข้อ จำกัด สำหรับขนาด URI ใน Opera
Daniel Kats

1
ไม่ทราบฉันรู้ว่าอาจเป็นข้อ จำกัด ของ adressbar แต่การทำสิ่งต่างๆด้วย AJAX อาจเป็นข้อยกเว้นเนื่องจากไม่จำเป็นต้องแสดงผล คุณต้องทดสอบมัน ถ้าเป็นที่ฉันฉันจะไม่ได้รับสายเบส 64 ในตอนแรก การคิดว่าเป็นการปฏิบัติที่ไม่ดีใช้หน่วยความจำและเวลามากขึ้นในการถอดรหัสและเข้ารหัส ตัวอย่างเช่นcreateObjectURLแทนที่จะreadAsDataURLดีกว่ามาก และหากคุณอัปโหลดไฟล์โดยใช้ ajax ให้เลือกFormDataแทนJSONหรือใช้canvas.toBlobแทนtoDataURL
Endless

7
ดียิ่งกว่าอินไลน์:await (await fetch(imageDataURL)).blob()
icl7126

3
แน่นอนว่าถ้าคุณกำหนดเป้าหมายเบราว์เซอร์ล่าสุด แต่นั่นก็ต้องใช้ฟังก์ชั่นที่จะอยู่ในฟังก์ชั่น async ด้วย การพูดของ ... await fetch(url).then(r=>r.blob())คือตัวเรียงลำดับ
ไม่มีที่สิ้นสุด

2
ทางออกที่เรียบร้อยมาก แต่ตามความรู้ของฉันจะไม่ทำงานกับ IE (กับ polyfill ofc) เนื่องจากAccess is denied.ข้อผิดพลาด ฉันเดาว่าfetchจะทำให้เกิดหยดภายใต้ URL หยด - ในทำนองเดียวกันURL.createObjectUrl- ซึ่งไม่สามารถทำงานได้เช่น ie11 การอ้างอิง อาจมีวิธีแก้ปัญหาบางอย่างในการใช้การดึงข้อมูลด้วย IE11? ดูเหมือนจะดีกว่าโซลูชันการซิงค์อื่น ๆ :)
Papi

72

การใช้งานที่ได้รับการปรับปรุง (แต่อ่านได้น้อย):

function base64toBlob(base64Data, contentType) {
    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = atob(base64Data);
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}

2
มีเหตุผลในการแบ่งไบต์เป็น blobs หรือไม่? หากฉันไม่ได้ใช้จะมีข้อเสียหรือความเสี่ยงหรือไม่?
Alfred Huang

ใช้งานได้ดีบน Android กับ Ionic 1 / Angular 1. Slice จำเป็นต้องใช้อย่างอื่นฉันจะใช้ OOM (Android 6.0.1)
Jürgen 'Kashban' Wahlmann

4
มีเพียงตัวอย่างเท่านั้นที่ฉันสามารถทำงานกับประเภทเอกสารใด ๆ ในสภาพแวดล้อมขององค์กรทั้ง IE 11 และ Chrome ได้อย่างราบรื่น
Santos

มันยอดเยี่ยมมาก ขอบคุณ!
elliotwesoff

คำอธิบายจะอยู่ในลำดับ เช่นทำไมมันมีประสิทธิภาพสูงขึ้น
Peter Mortensen

19

สำหรับการสนับสนุนเบราว์เซอร์ทั้งหมดโดยเฉพาะบน Android คุณอาจเพิ่มสิ่งนี้:

try{
    blob = new Blob(byteArrays, {type : contentType});
}
catch(e){
    // TypeError old Google Chrome and Firefox
    window.BlobBuilder = window.BlobBuilder ||
                         window.WebKitBlobBuilder ||
                         window.MozBlobBuilder ||
                         window.MSBlobBuilder;
    if(e.name == 'TypeError' && window.BlobBuilder){
        var bb = new BlobBuilder();
        bb.append(byteArrays);
        blob = bb.getBlob(contentType);
    }
    else if(e.name == "InvalidStateError"){
        // InvalidStateError (tested on FF13 WinXP)
        blob = new Blob(byteArrays, {type : contentType});
    }
    else{
        // We're screwed, blob constructor unsupported entirely
    }
}

ขอขอบคุณ แต่มีปัญหาสองประการเกี่ยวกับข้อมูลโค้ดที่คุณเขียนด้านบนถ้าฉันอ่านถูกต้อง: (1) โค้ดที่อยู่ใน catch () ในอื่น ๆ สุดท้าย - ถ้าเหมือนกับโค้ดต้นฉบับภายในลอง (): "blob = ใหม่ Blob (byteArrays, {type: contentType}) "... ฉันไม่ทราบสาเหตุที่คุณแนะนำให้ทำซ้ำรหัสเดียวกันหลังจากข้อยกเว้นเดิม? ... (2) BlobBuilder.append () ไม่สามารถยอมรับ bytes-arrays แต่เป็น ArrayBuffer ดังนั้นอินพุตไบต์อาร์เรย์ต้องถูกแปลงเพิ่มเติมเป็น ArrayBuffer ก่อนใช้ API นี้ REF: developer.mozilla.org/en-US/docs/Web/API/BlobBuilder
Panini Luncher

14

สำหรับข้อมูลภาพฉันพบว่าใช้ง่ายกว่าcanvas.toBlob(แบบอะซิงโครนัส)

function b64toBlob(b64, onsuccess, onerror) {
    var img = new Image();

    img.onerror = onerror;

    img.onload = function onload() {
        var canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;

        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

        canvas.toBlob(onsuccess);
    };

    img.src = b64;
}

var base64Data = 'data:image/jpg;base64,/9j/4AAQSkZJRgABAQA...';
b64toBlob(base64Data,
    function(blob) {
        var url = window.URL.createObjectURL(blob);
        // do something with url
    }, function(error) {
        // handle error
    });

1
ฉันเดาว่าคุณปล่อยข้อมูลบางส่วนกับที่ ... เช่น meta info มันเหมือนกับการแปลงภาพเป็น png ดังนั้นมันจึงไม่ได้ผลลัพธ์เดียวกันมันก็ใช้ได้กับรูปภาพเท่านั้น
Endless

ฉันเดาว่าคุณสามารถปรับปรุงได้โดยการแยกประเภทอิมเมจimage/jpgจากสตริง base64 แล้วส่งมันเป็นพารามิเตอร์ตัวที่สองในtoBlobฟังก์ชั่นเพื่อให้ผลลัพธ์เป็นประเภทเดียวกัน นอกเหนือจากนั้นฉันคิดว่ามันสมบูรณ์แบบ - ช่วยลดปริมาณการรับส่งข้อมูล 30% และพื้นที่ดิสก์ของคุณบนเซิร์ฟเวอร์ (เทียบกับฐาน 64) และใช้งานได้ดีแม้กับ PNG แบบโปร่งใส
icl7126

1
ฟังก์ชั่นขัดข้องด้วยภาพที่มีขนาดใหญ่กว่า 2MB ... ใน Android ฉันได้รับการยกเว้น: android.os.TransactionTooLarge
Ruben

14

ดูตัวอย่างนี้: https://jsfiddle.net/pqhdce2L/

function b64toBlob(b64Data, contentType, sliceSize) {
  contentType = contentType || '';
  sliceSize = sliceSize || 512;

  var byteCharacters = atob(b64Data);
  var byteArrays = [];

  for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    var slice = byteCharacters.slice(offset, offset + sliceSize);

    var byteNumbers = new Array(slice.length);
    for (var i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    var byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }
    
  var blob = new Blob(byteArrays, {type: contentType});
  return blob;
}


var contentType = 'image/png';
var b64Data = Your Base64 encode;

var blob = b64toBlob(b64Data, contentType);
var blobUrl = URL.createObjectURL(blob);

var img = document.createElement('img');
img.src = blobUrl;
document.body.appendChild(img);


คำอธิบายจะอยู่ในลำดับ
Peter Mortensen

9

ฉันสังเกตว่า Internet Explorer 11 นั้นช้ามากอย่างไม่น่าเชื่อเมื่อแบ่งข้อมูลตามที่ Jeremy แนะนำ สิ่งนี้เป็นจริงสำหรับ Chrome แต่ Internet Explorer ดูเหมือนว่ามีปัญหาเมื่อส่งข้อมูลที่ถูกหั่นไปยังตัวสร้าง Blob บนเครื่องของฉันการส่งผ่านข้อมูล 5 MB ทำให้ Internet Explorer ขัดข้องและปริมาณการใช้หน่วยความจำผ่านหลังคา Chrome สร้างหยดในเวลาไม่นาน

เรียกใช้รหัสนี้เพื่อเปรียบเทียบ:

var byteArrays = [],
    megaBytes = 2,
    byteArray = new Uint8Array(megaBytes*1024*1024),
    block,
    blobSlowOnIE, blobFastOnIE,
    i;

for (i = 0; i < (megaBytes*1024); i++) {
    block = new Uint8Array(1024);
    byteArrays.push(block);
}

//debugger;

console.profile("No Slices");
blobSlowOnIE = new Blob(byteArrays, { type: 'text/plain'});
console.profileEnd();

console.profile("Slices");
blobFastOnIE = new Blob([byteArray], { type: 'text/plain'});
console.profileEnd();

ดังนั้นฉันจึงตัดสินใจรวมทั้งวิธีการที่เจเรมีอธิบายไว้ในฟังก์ชั่นเดียว เครดิตไปหาเขาสำหรับเรื่องนี้

function base64toBlob(base64Data, contentType, sliceSize) {

    var byteCharacters,
        byteArray,
        byteNumbers,
        blobData,
        blob;

    contentType = contentType || '';

    byteCharacters = atob(base64Data);

    // Get BLOB data sliced or not
    blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();

    blob = new Blob(blobData, { type: contentType });

    return blob;


    /*
     * Get BLOB data in one slice.
     * => Fast in Internet Explorer on new Blob(...)
     */
    function getBlobDataAtOnce() {
        byteNumbers = new Array(byteCharacters.length);

        for (var i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }

        byteArray = new Uint8Array(byteNumbers);

        return [byteArray];
    }

    /*
     * Get BLOB data in multiple slices.
     * => Slow in Internet Explorer on new Blob(...)
     */
    function getBlobDataSliced() {

        var slice,
            byteArrays = [];

        for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            slice = byteCharacters.slice(offset, offset + sliceSize);

            byteNumbers = new Array(slice.length);

            for (var i = 0; i < slice.length; i++) {
                byteNumbers[i] = slice.charCodeAt(i);
            }

            byteArray = new Uint8Array(byteNumbers);

            // Add slice
            byteArrays.push(byteArray);
        }

        return byteArrays;
    }
}

ขอบคุณที่รวมสิ่งนี้ ด้วยการอัพเดทล่าสุดเป็น IE11 (ระหว่าง 5/2016 ถึง 8/2016) การสร้าง blobs จากอาร์เรย์เริ่มมีขนาดใหญ่ขึ้นของ ram โดยการส่ง Uint8Array เดียวไปยังตัวสร้างบล็อกมันใช้งานแทบไม่มีหน่วยความจำและเสร็จสิ้นกระบวนการจริง
Andrew Vogel

การเพิ่มขนาดชิ้นงานในตัวอย่างทดสอบจาก 1K เป็น 8..16K จะช่วยลดเวลาใน IE ได้อย่างมาก บนโค้ดดั้งเดิมของพีซีของฉันใช้เวลา 5 ถึง 8 วินาทีโค้ดที่มี 8K บล็อกใช้เวลาเพียง 356ms และ 225ms สำหรับบล็อก 16K
Victor

6

สำหรับผู้ชื่นชอบการคัดลอกวางแบบฉันอย่างนี้นี่คือฟังก์ชั่นดาวน์โหลดที่ปรุงสุกซึ่งทำงานบน Chrome, Firefox และ Edge

window.saveFile = function (bytesBase64, mimeType, fileName) {
var fileUrl = "data:" + mimeType + ";base64," + bytesBase64;
fetch(fileUrl)
    .then(response => response.blob())
    .then(blob => {
        var link = window.document.createElement("a");
        link.href = window.URL.createObjectURL(blob, { type: mimeType });
        link.download = fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    });
}

createObjectURLไม่ยอมรับการโต้แย้งที่ 2 ...
ไม่มีที่สิ้นสุด

5

หากคุณสามารถยืนเพิ่มการพึ่งพาหนึ่งโครงการของคุณมีblob-utilแพคเกจ npmที่ยอดเยี่ยมที่ให้base64StringToBlobฟังก์ชั่นที่มีประโยชน์ เมื่อเพิ่มไปยังของpackage.jsonคุณแล้วคุณสามารถใช้สิ่งนี้:

import { base64StringToBlob } from 'blob-util';

const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

const blob = base64StringToBlob(b64Data, contentType);

// Do whatever you need with your blob...

3

ฉันโพสต์วิธีการประกาศการแปลงการแปลง Base64 ให้ชัดเจนยิ่งขึ้น ในขณะที่ async fetch().blob()นั้นเนี๊ยบมากและฉันชอบโซลูชันนี้มากมันไม่ทำงานบน Internet Explorer 11 (และอาจเป็น Edge - ฉันยังไม่ได้ทดสอบตัวนี้) ถึงแม้จะเป็น polyfill ก็ตามลองดูความคิดเห็นของฉันที่ไม่มีที่สิ้นสุด ' โพสต์เพื่อดูรายละเอียดเพิ่มเติม

const blobPdfFromBase64String = base64String => {
   const byteArray = Uint8Array.from(
     atob(base64String)
       .split('')
       .map(char => char.charCodeAt(0))
   );
  return new Blob([byteArray], { type: 'application/pdf' });
};

โบนัส

หากคุณต้องการพิมพ์คุณสามารถทำสิ่งที่ชอบ:

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // Or however you want to check it
const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

โบนัส x 2 - การเปิดไฟล์ BLOB ในแท็บใหม่สำหรับ Internet Explorer 11

หากคุณสามารถทำการ preprocessing ของสตริง Base64 บนเซิร์ฟเวอร์คุณสามารถแสดงมันภายใต้ URL บางส่วนและใช้ลิงค์ในprintJS:)


2

ต่อไปนี้เป็นรหัส TypeScript ของฉันซึ่งสามารถแปลงเป็น JavaScript ได้อย่างง่ายดายและคุณสามารถใช้

/**
 * Convert BASE64 to BLOB
 * @param Base64Image Pass Base64 image data to convert into the BLOB
 */
private convertBase64ToBlob(Base64Image: any) {
    // Split into two parts
    const parts = Base64Image.split(';base64,');

    // Hold the content type
    const imageType = parts[0].split(':')[1];

    // Decode Base64 string
    const decodedData = window.atob(parts[1]);

    // Create UNIT8ARRAY of size same as row data length
    const uInt8Array = new Uint8Array(decodedData.length);

    // Insert all character code into uInt8Array
    for (let i = 0; i < decodedData.length; ++i) {
        uInt8Array[i] = decodedData.charCodeAt(i);
    }

    // Return BLOB image after conversion
    return new Blob([uInt8Array], { type: imageType });
}

4
ในขณะที่ข้อมูลโค้ดนี้อาจเป็นโซลูชันรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพการโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
Johan

2
นอกจากนี้ทำไมคุณถึงตะโกนใส่ความคิดเห็น?
canbax

4
ของคุณรหัสมีเพียงชนิดเดียวและชนิดที่เป็นTypescript code anyชอบทำไมตื๊อ
zoran404

0

วิธีที่มีการดึงข้อมูลเป็นทางออกที่ดีที่สุด แต่ถ้าใครต้องการใช้วิธีที่ไม่มีการดึงข้อมูลนี่ก็เป็นเพราะวิธีที่กล่าวมาก่อนหน้านี้ใช้งานไม่ได้สำหรับฉัน:

function makeblob(dataURL) {
    const BASE64_MARKER = ';base64,';
    const parts = dataURL.split(BASE64_MARKER);
    const contentType = parts[0].split(':')[1];
    const raw = window.atob(parts[1]);
    const rawLength = raw.length;
    const uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }

    return new Blob([uInt8Array], { type: contentType });
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.