Как получить файл или большой двоичный объект из URL объекта?
Я позволяю пользователю загружать изображения на страницу с помощью перетаскивания и других методов. Когда изображение отбрасывается, я использую URL.createObjectURL
для преобразования в URL объекта для отображения изображения. Я не отменяю url-адрес, так как я его повторно использую.
Итак, когда придет время создать FormData
объект, поэтому я могу позволить им загрузить форму с одним из этих изображений в нем, есть ли способ, которым я могу отменить этот URL-адрес объекта обратно в Blob
или File
поэтому я могу добавить его к FormData
возражаете?
6 ответов:
Как указывает генгкев в своем комментарии выше, похоже, что лучший / единственный способ сделать это - с помощью асинхронного вызова xhr2:
var xhr = new XMLHttpRequest(); xhr.open('GET', 'blob:http%3A//your.blob.url.here', true); xhr.responseType = 'blob'; xhr.onload = function(e) { if (this.status == 200) { var myBlob = this.response; // myBlob is now the blob that the object URL pointed to. } }; xhr.send();
возможно, кто-то находит это полезным при работе с React/Node/Axios. Я использовал это для моей функции загрузки изображений Cloudinary с
react-dropzone
в пользовательском интерфейсе.axios({ method: 'get', url: file[0].preview, // blob url eg. blob:http://127.0.0.1:8000/e89c5d87-a634-4540-974c-30dc476825cc responseType: 'blob' }).then(function(response){ var reader = new FileReader(); reader.readAsDataURL(response.data); reader.onloadend = function() { var base64data = reader.result; self.props.onMainImageDrop(base64data) } })
посмотреть получение данных BLOB из запроса XHR что указывает на то, что BlobBuilder не работает в Chrome, поэтому вам нужно использовать:
xhr.responseType = 'arraybuffer';
Если вы все равно покажете файл на холсте, вы также можете преобразовать содержимое холста в объект blob.
canvas.toBlob(function(my_file){ //.toBlob is only implemented in > FF18 but there is a polyfill //for other browsers https://github.com/blueimp/JavaScript-Canvas-to-Blob var myBlob = (my_file); })
современное решение:
let blob = await fetch(url).then(r => r.blob());
url-адрес может быть url-адресом объекта или обычным url-адресом.
у меня есть веб-сайт, который потребляет изображения из хранилища Amazon S3 / Azure, и там я храню объекты с именами uniqueidentifiers:
пример: http://****. blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf
некоторые из этих изображений должны быть загружены из нашего системного интерфейса. Чтобы избежать передачи этого трафика через мой HTTP-сервер, поскольку для доступа к этим объектам не требуется никакой безопасности (кроме фильтрации домена), я решил сделать прямой запрос в браузере пользователя и использовать локальную обработку, чтобы дать файлу реальный имя и расширение.
для этого я использовал эту замечательную статью от Генри Альгуса: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
1. Первый шаг: Добавьте двоичную поддержку в jquery
/** * * jquery.binarytransport.js * * @description. jQuery ajax transport for making binary data type requests. * @version 1.0 * @author Henry Algus <henryalgus@gmail.com> * */ // use this transport for "binary" data type $.ajaxTransport("+binary", function (options, originalOptions, jqXHR) { // check for conditions and support for blob / arraybuffer response type if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))) { return { // create new XMLHttpRequest send: function (headers, callback) { // setup all variables var xhr = new XMLHttpRequest(), url = options.url, type = options.type, async = options.async || true, // blob or arraybuffer. Default is blob dataType = options.responseType || "blob", data = options.data || null, username = options.username || null, password = options.password || null; xhr.addEventListener('load', function () { var data = {}; data[options.dataType] = xhr.response; // make callback and send data callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders()); }); xhr.open(type, url, async, username, password); // setup custom headers for (var i in headers) { xhr.setRequestHeader(i, headers[i]); } xhr.responseType = dataType; xhr.send(data); }, abort: function () { jqXHR.abort(); } }; } });
2. Второй шаг: сделайте запрос, используя этот тип транспорта.
function downloadArt(url) { $.ajax(url, { dataType: "binary", processData: false }).done(function (data) { // just my logic to name/create files var filename = url.substr(url.lastIndexOf('/') + 1) + '.png'; var blob = new Blob([data], { type: 'image/png' }); saveAs(blob, filename); }); }
теперь вы можете использовать Blob созданный как вы хотите, в моем случае я хочу сохранить его диск.
3. Необязательно: сохраните файл на компьютере пользователя с помощью FileSaver
я использовал FileSaver.js чтобы сохранить на диск загруженный файл, если вам нужно это сделать, пожалуйста, используйте эту библиотеку javascript:
https://github.com/eligrey/FileSaver.js/
Я надеюсь, это поможет другим с более конкретными потребностями.