Как преобразовать Blob в файл в JavaScript


111

Мне нужно загрузить изображение на сервер NodeJS в какой-то каталог. Для этого я использую connect-busboyмодуль узла.

У меня был dataURLобраз, который я преобразовал в blob, используя следующий код:

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});
}

Мне нужен способ преобразовать большой двоичный объект в файл для загрузки изображения.

Может ли кто-нибудь помочь мне с этим?


4
Файлы - это большие двоичные объекты, просто добавьте мета-свойства, и все готово.
dandavis

1
Значение по умолчанию для большого двоичного объекта при его загрузке - blob. Итак, я сначала извлек имя файла, который я обрезал, а затем дал то же самое, filenameчтобы обрезать файл, загружая его на сервер путем выполнения form.append("blob",blob, filename);.
пропустить

@skip помог мой ответ ниже? Так, отметьте, пожалуйста, правильный ответ.
CBarr

Ответы:


150

Эта функция преобразует a Blobв a, Fileи у меня она отлично работает.

Ванильный 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 (с правильной типизацией)

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;
}

использование

var myBlob = new Blob();

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

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

3
Я думаю, что приведение должно произойти первым, поэтому вам не нужно использовать anyTypeScript. См. Этот пример.
Styfle

3
Это не работает для всех целей. Добавление этого «файла» к вызову ajax не приведет к правильной установке имени файла.
Джейкоб Пол Ричардт

13
Это не лучшее решение, созданный объект по-прежнему является каплей.
czupe

4
Просто добавьте b.__proto__ = File.prototype, и ваше решение становится мечтой , что даже трюки b instanceOf Fileнаtrue
manuelnaranjo

3
Это не должен быть принятый ответ, должно быть stackoverflow.com/a/53205768/2557517 или stackoverflow.com/a/31663645/2557517 .
Кира

204

Вы можете использовать конструктор файлов:

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

Согласно спецификации w3, это добавит байты, содержащиеся в большом двоичном объекте, к байтам для нового объекта File, и создаст файл с указанным именем http://www.w3.org/TR/FileAPI/#dfn-file


2
Это то, что я искал, с той лишь разницей, что первый аргумент на самом деле является массивом, поэтому я использовал его как: var file = new File ([myBlob], "name");
Michaeldcooney

1
Да. Я тоже ищу это решение. Сервер Stamplay не может получить имя файла из объекта blob. Поэтому мне нужно преобразовать его обратно в файл. Но Safari не поддерживает файловый API ... Вернемся к 0 сейчас :(
Хью Хоу,

4
Конструкторы файлов не работают, например, в PhantomJS:TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')
bkimminich

7
В Edge в настоящее время (2017-10-04) есть ошибка, которая не позволяет использовать этот конструктор. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
Рик Мартинс,

8
Обязательно добавьте тип файла, иначе он не будет работать должным образом. новый файл ([myBlob], "name", {type: "image / jpeg",});
BernardA 07

34

Ответ Джошуа П. Никсона правильный, но мне также пришлось установить дату последнего изменения. так вот код.

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

1534584790000 - это временная метка unix для « GMT: суббота, 18 августа 2018 г., 9:33:10 AM ».


3
Очки за то, что не ломались, instanceofкак принятый ответ
Мэтт Дженсен

15

Чтобы я работал, мне пришлось явно указать тип, хотя он содержится в большом двоичном объекте:

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

14

Мой современный вариант:

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

2
Чтобы добавить имя файла к полученному файлу, используйте:fd.set('a', blobData, 'filename')
joaoguerravieira

Он не работает в некоторых устройствах IOS, когдаfd.set
Пойте

Спасибо. это работает, теперь мне не нужно преобразовывать blob в файл.
xreyc_developer22


2

Машинопись

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 })
}

Вывод

Скриншот

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.