javascript - not - ¿Cómo obtener un archivo o blob de una URL de objeto?
read file javascript (5)
Permitiré al usuario cargar imágenes en una página mediante arrastrar y soltar y otros métodos. Cuando se descarta una imagen, uso URL.createObjectURL
para convertirla a una URL de objeto para mostrar la imagen. No estoy revocando la url, ya que la reutilizo.
Entonces, cuando llega el momento de crear un objeto FormData
para poder cargar un formulario con una de esas imágenes, ¿hay alguna forma de que pueda revertir ese Object URL en un Blob
o un File
para que pueda adjuntarlo? a un objeto FormData
?
Como gengkev alude en su comentario anterior, parece que la mejor y única forma de hacerlo es con una llamada 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();
Consulte Obtener datos BLOB de la solicitud XHR, que señala que BlobBuilder no funciona en Chrome, por lo que debe usar:
xhr.responseType = ''arraybuffer'';
Desafortunadamente la respuesta de @ BrianFreud no se ajusta a mis necesidades, tenía una necesidad diferente, y sé que esa no es la respuesta para la pregunta de @ BrianFreud, pero la dejo aquí porque muchas personas llegaron aquí con mi misma necesidad. Necesitaba algo como ''¿Cómo obtener un archivo o blob de una URL?'', Y la respuesta correcta actual no se ajusta a mis necesidades porque no es de dominio cruzado.
Tengo un sitio web que consume imágenes de un Amazon S3 / Azure Storage, y allí almaceno los objetos nombrados con uniqueidentifiers:
muestra: http: //****.blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf
Algunas de estas imágenes deben descargarse de nuestra interfaz del sistema. Para evitar pasar este tráfico a través de mi servidor HTTP, ya que estos objetos no requieren acceso a seguridad (excepto por filtrado de dominio), decidí hacer una solicitud directa en el navegador del usuario y usar el procesamiento local para darle un nombre real al archivo y extensión.
Para lograrlo, he usado este gran artículo de Henry Algus: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
1. Primer paso: agregar soporte binario a 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. Segundo paso: realice una solicitud utilizando este tipo de transporte.
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);
});
}
Ahora puede usar el Blob creado como lo desee, en mi caso quiero guardarlo en el disco.
3. Opcional: Guardar archivo en la computadora del usuario usando FileSaver
He utilizado FileSaver.js para guardar en el disco el archivo descargado, si necesita lograr eso, use esta biblioteca de JavaScript:
https://github.com/eligrey/FileSaver.js/
Espero que esto ayude a otros con necesidades más específicas.
Si muestra el archivo en un lienzo de todos modos, también puede convertir el contenido del lienzo en un objeto 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);
})
Tal vez alguien encuentre esto útil cuando se trabaja con React / Node / Axios. Lo usé para mi función de carga de imágenes en Cloudinary con react-dropzone
en la interfaz de usuario.
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)
}
})