Làm thế nào để chuyển đổi Blob thành Tệp trong JavaScript


111

Tôi cần tải một hình ảnh lên máy chủ NodeJS vào một số thư mục. Tôi đang sử dụng connect-busboymô-đun nút cho điều đó.

Tôi đã có dataURLhình ảnh mà tôi đã chuyển đổi thành blob bằng cách sử dụng mã sau:

dataURLToBlob: function(dataURL) {
    var BASE64_MARKER = ';base64,';
    if (dataURL.indexOf(BASE64_MARKER) == -1) {
        var parts = dataURL.split(',');
        var contentType = parts[0].split(':')[1];
        var raw = decodeURIComponent(parts[1]);
        return new Blob([raw], {type: contentType});
    }
    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
}

Tôi cần một cách để chuyển đổi blob thành một tệp để tải lên hình ảnh.

Ai đó có thể giúp tôi với nó?


4
Các tệp là các Khối, chỉ cần giải quyết các thuộc tính meta và bạn đã sẵn sàng.
dandavis

1
Mặc định cho một đốm màu khi tải nó lên blob. Vì vậy, đầu tiên tôi trích xuất tên của tệp tôi đang cắt và sau đó đặt cùng filenametên tệp đã cắt trong khi tải nó lên máy chủ bằng cách thực hiện form.append("blob",blob, filename);.
bỏ qua

@skip câu trả lời của tôi bên dưới có giúp được gì không? Là như vậy, hãy đánh dấu nó là câu trả lời đúng.
CBarr

Câu trả lời:


149

Hàm này chuyển đổi a Blobthành a Filevà nó hoạt động rất tốt đối với tôi.

Vanilla JavaScript

function blobToFile(theBlob, fileName){
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    theBlob.lastModifiedDate = new Date();
    theBlob.name = fileName;
    return theBlob;
}

TypeScript (với cách đánh máy thích hợp)

public blobToFile = (theBlob: Blob, fileName:string): File => {
    var b: any = theBlob;
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    b.lastModifiedDate = new Date();
    b.name = fileName;

    //Cast to a File() type
    return <File>theBlob;
}

Sử dụng

var myBlob = new Blob();

//do stuff here to give the blob some data...

var myFile = blobToFile(myBlob, "my-image.png");

3
Tôi nghĩ quá trình ép diễn nên xảy ra đầu tiên nên bạn không cần sử dụng anytrong TypeScript. Hãy xem ví dụ này .
styfle

2
Điều này không hoạt động cho tất cả các mục đích. Thêm "Tệp" này vào lệnh gọi ajax sẽ không đặt tên tệp chính xác.
Jacob Poul Richardt

12
Đây không phải là một giải pháp tốt, đối tượng được tạo ra vẫn là một đốm màu.
czupe

4
Chỉ cần thêm b.__proto__ = File.prototype, và giải pháp của bạn sẽ trở thành một giấc mơ mà ngay cả thủ đoạn b instanceOf Fileđểtrue
manuelnaranjo

3
Đây không phải là câu trả lời được chấp nhận, nên là stackoverflow.com/a/53205768/2557517 hoặc stackoverflow.com/a/31663645/2557517 .
Kira

204

Bạn có thể sử dụng phương thức khởi tạo Tệp:

var file = new File([myBlob], "name");

Theo đặc tả w3, điều này sẽ nối các byte mà blob chứa vào các byte cho đối tượng Tệp mới và tạo tệp với tên được chỉ định http://www.w3.org/TR/FileAPI/#dfn-file


2
Đây là những gì tôi đang tìm kiếm, một sự khác biệt là đối số đầu tiên thực sự là một mảng nên tôi đã sử dụng nó như: var file = new File ([myBlob], "name");
Michaeldcooney

1
Đúng. Tôi cũng đang tìm kiếm giải pháp này. Máy chủ Stamplay không thể lấy tên tệp từ đối tượng blob. Vì vậy, tôi cần phải chuyển đổi nó trở lại tập tin. Nhưng Safari không hỗ trợ tệp API ... trở về 0 ngay bây giờ :(
Hugh Hou

4
Tập tin nhà xây dựng không làm việc ví dụ như trong PhantomJS:TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')
bkimminich

7
Edge hiện có (2017-10-04) một lỗi ngăn cản việc sử dụng hàm tạo này. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
Rik Martins

8
Hãy chắc chắn thêm loại tệp, nếu không nó sẽ không hoạt động bình thường. new File ([myBlob], "name", {type: "image / jpeg",});
BernardA

34

Câu trả lời của Joshua P Nixon là đúng nhưng tôi cũng phải đặt ngày sửa đổi lần cuối. vì vậy đây là mã.

var file = new File([blob], "file_name", {lastModified: 1534584790000});

1534584790000 là một dấu thời gian unix cho " GMT: Thứ Bảy, ngày 18 tháng 8 năm 2018 9:33:10 AM "


3
Điểm để không vi phạm instanceofnhư câu trả lời được chấp nhận
Matt Jensen

15

Để làm việc, tôi phải cung cấp rõ ràng loại mặc dù nó được chứa trong blob bằng cách làm như vậy:

const file = new File([blob], 'untitled', { type: blob.type })

13

Biến thể hiện đại của tôi :

function blob2file(blobData) {
  const fd = new FormData();
  fd.set('a', blobData);
  return fd.get('a');
}

2
Để thêm một tên tập tin để kết quả sử dụng file:fd.set('a', blobData, 'filename')
joaoguerravieira

Nó không thành công trong một số thiết bị IOS khifd.set
Sing

cảm ơn. Điều này hoạt động, Bây giờ tôi không phải chuyển đổi blob thành tệp.
xreyc_developer22


2

Chữ viết

public blobToFile = (theBlob: Blob, fileName:string): File => {       
    return new File([theBlob], fileName, { lastModified: new Date().getTime(), type: theBlob.type })
}

Javascript

function blobToFile(theBlob, fileName){       
    return new File([theBlob], fileName, { lastModified: new Date().getTime(), type: theBlob.type })
}

Đầu ra

ảnh chụp màn hình

File {name: "fileName", lastModified: 1597081051454, lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time), webkitRelativePath: "", size: 601887, …}
lastModified: 1597081051454
lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time) {}
name: "fileName"
size: 601887
type: "image/png"
webkitRelativePath: ""
__proto__: File
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.