Как получить файл или blob из URL-адреса объекта?
Я разрешаю пользователю загружать изображения на страницу с помощью перетаскивания и других методов. Когда изображение удаляется, я использую URL.createObjectURL
для преобразования в URL объекта для отображения изображения. Я не отменяю URL, как я его повторно использую.
Итак, когда приходит время создать объект FormData
чтобы я мог разрешить им загружать форму с одним из этих изображений в нем, есть ли какой-нибудь способ, которым я могу затем повернуть этот URL объекта обратно в Blob
объект или File
чтобы затем добавить это к объекту FormData
?
Ответы
Ответ 1
Как упоминает gengkev в своем комментарии выше, похоже, что лучший/единственный способ сделать это - вызов async 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();
Обновление (2018): В ситуациях, когда можно безопасно использовать ES5, у Джо есть более простой ответ на основе ES5 ниже.
Ответ 2
Современное решение:
let blob = await fetch(url).then(r => r.blob());
URL может быть URL объекта или обычным URL.
Ответ 3
Может быть, кто-то найдет это полезным при работе с React/Node/Axios. Я использовал это для своей функции загрузки облачного изображения с помощью 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)
}
})
Ответ 4
См. Получение BLOB-данных из запроса XHR, в котором указывается, что BlobBuilder не работает в Chrome, поэтому вам нужно использовать:
xhr.responseType = 'arraybuffer';
Ответ 5
Если вы покажете файл в холсте, вы также можете преобразовать содержимое холста в объект 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);
})
Ответ 6
К сожалению, ответ @BrianFreud не соответствует моим потребностям, у меня была небольшая разница, и я знаю, что это не ответ на вопрос @BrianFreud, но я оставляю его здесь, потому что многие люди попали сюда с моими же необходимость. Мне нужно было что-то вроде "Как получить файл или blob из URL?", И текущий правильный ответ не соответствует моим потребностям, потому что он не является междоменным.
У меня есть веб-сайт, который расходует изображения из хранилища Amazon S3/Azure и там хранятся объекты с уникальными идентификаторами:
: 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 <[email protected]>
*
*/
// 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/
Я ожидаю, что это поможет другим с более конкретными потребностями.
Ответ 7
Используя fetch, например, как показано ниже:
fetch(<"yoururl">, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + <your access token if need>
},
})
.then((response) => response.blob())
.then((blob) => {
// 2. Create blob link to download
const url = window.URL.createObjectURL(new Blob([blob]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'sample.xlsx');
// 3. Append to html page
document.body.appendChild(link);
// 4. Force download
link.click();
// 5. Clean up and remove the link
link.parentNode.removeChild(link);
})
Вы можете вставить в консоль Chrome для тестирования. файл с загрузкой с помощью sample.xlsx. Надеюсь, это поможет!