Як надати Blob-файлу, завантаженому як FormData, ім'я файлу?


78

Зараз я завантажую зображення, вставлені з буфера обміну з таким кодом:

// Turns out getAsFile will return a blob, not a file
var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();
form.append("blob",blob);
request.open(
            "POST",
            "/upload",
            true
        );
request.send(form);

Виходить завантажене поле форми з отриманням імені, подібного до цього: Blob157fce71535b4f93ba92ac6053d81e3a

Чи є спосіб встановити це або отримати це ім'я файлу на стороні клієнта, не роблячи жодного зв'язку на стороні сервера?

Відповіді:


146

Для Chrome, Safari та Firefox просто використовуйте це:

form.append("blob", blob, filename);

(див. документацію MDN )


Де ти про це помітив ??? Це чудово! Чи є посилання на підтримку версій Chrome?
Дмитро Сорін

До речі, це в специфікації: w3.org/TR/XMLHttpRequest2/#interface-formdata
Дмитро Сорін

1
Крім того, я працюю над помилкою firefox, щоб виправити цю проблему, я її вже виправив, але у мене є деякі "проблеми зі стилем" bugzilla.mozilla.org/show_bug.cgi?id=690659 (наразі мені не потрібно виправте цей патч, так що якщо хтось захоче його забрати, я його більш ніж задоволений)
Chiguireitor

@Chiguireitor його все ще не виправлено?
Буде

3
Ось "таблиця сумісності" від MDN. Зверніть увагу, що станом на цей пост додаток з іменем файлу має хитку підтримку у всіх браузерах, крім Chrome та FF: developer.mozilla.org/en-US/docs/Web/API/…
Адам,

34

Додаючи це сюди, оскільки, здається, його тут немає.

Окрім чудового рішення, form.append("blob",blob, filename);ви також можете перетворити BLOB на Fileпримірник:

var blob = new Blob([JSON.stringify([0,1,2])], {type : 'application/json'});
var fileOfBlob = new File([blob], 'aFileName.json');
form.append("upload", fileOfBlob);

1
Проблема в тому, що ви отримуєте файл / крапку з буфера обміну. Те , що ви описуєте , пов'язані з цим питанням: stackoverflow.com/questions/27251953 / ...
jontro

9
не працює в IE, оскільки все ще не підтримує конструктор файлів.
Махіб

Документація @Mahib MDN щодо Fileконструктора передбачає, що він підтримується з IE10 і вище.
Роберт К. Белл

2
@ RobertK.Bell, я практично перевірив Edge, і це не спрацювало :(, тоді мені довелося перейти на конструктор BLOB-
об'єктів

1
@Mahib Ви маєте рацію - випуск # 9551546 на File конструкторі трекера Edge видаєFunction Expected виняток
Роберт К. Белл

3

Оскільки ви отримуєте дані, вставлені в буфер обміну, немає надійного способу дізнатися про походження файлу та його властивості (включаючи ім’я).

Найкраще поставити власну схему іменування файлів і надіслати разом із крапкою.

form.append("filename",getFileName());
form.append("blob",blob);

function getFileName() {
 // logic to generate file names
}

1
Питання не вимагає оригінального імені файлу. Ця відповідь повністю не відповідає цілі.
Niels Abildgaard

2
@NielsAbildgaard: Справді? Він запитує про присвоєння імені файлу, і чи не відповідає оригінальне ім’я файлу дійсним?
Mrchief

1
Відповідь не відповідає на вихідне запитання (крім "ось альтернатива") і дає відповідь на те, що не задається, і, чесно кажучи, не в темі.
Niels Abildgaard,

2

Це ім’я виглядає похідним від GUID URL-адреси об’єкта. Виконайте наступне, щоб отримати URL-адресу об’єкта, з якої походить ім’я.

var URL = self.URL || self.webkitURL || self;
var object_url = URL.createObjectURL(blob);
URL.revokeObjectURL(object_url);

object_urlбуде відформатовано як blob:{origin}{GUID}у Google Chrome та moz-filedata:{GUID}у Firefox. Початком є ​​протокол + хост + нестандартний порт для протоколу. Наприклад, blob:http://stackoverflow.com/e7bc644d-d174-4d5e-b85d-beeb89c17743або blob:http://[::1]:123/15111656-e46c-411d-a697-a09d23ec9a99. Ви, ймовірно, хочете витягти GUID і видалити всі тире.


1

Не тестував, але це повинно попередити URL-адресу даних BLOB:

var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();

var reader = new FileReader();
reader.onload = function(event) {
  alert(event.target.result); // <-- data url
};
reader.readAsDataURL(blob);

Це дійсно сповістить BLOB-адресу як URL-адресу даних. Що я хочу отримати / встановити, це ім'я файлу, прикріплене до поля форми під час завантаження форми.
jontro

Тоді я не знаю способу без зв'язку на стороні сервера.
JochenJung

0

Це насправді залежить від того, як сконфігурований сервер з іншого боку та з якими модулями для того, як він обробляє повідомлення BLOB. Ви можете спробувати вказати потрібне ім’я у шляху до вашої публікації.

request.open(
    "POST",
    "/upload/myname.bmp",
    true
);

0

Чи використовуєте ви Google App Engine? Ви можете використовувати файли cookie (створені за допомогою JavaScript), щоб підтримувати зв'язок між іменами файлів та іменем, отриманим від сервера.


0

Коли ви використовуєте Google Chrome, ви можете використовувати / зловживати Google Filesystem APIцим. Тут ви можете створити файл із зазначеним іменем та записати до нього вміст BLOB-об'єкта. Тоді ви можете повернути результат користувачеві.

Я ще не знайшов хорошого способу для Firefox; ймовірно, downloadifyдля назви краплини потрібен невеликий фрагмент Flash, подібний до цього.

IE10 має msSaveBlob()функцію в BlobBuilder.

Можливо, це більше для завантаження крапки, але це пов’язано.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.