Comment obtenir un fichier ou un blob à partir d'une URL d'objet?

j'autorise l'utilisateur à charger des images dans une page via drag&drop et d'autres méthodes. Quand une image est abandonnée, j'utilise URL.createObjectURL pour convertir en une URL d'objet pour afficher l'image. Je ne révoque pas l'url, car je la réutilise.

donc, quand vient le temps de créer un objet FormData pour que je puisse leur permettre de télécharger un formulaire avec une de ces images, est-ce qu'il y a un moyen que je puisse ensuite inverser L'URL de cet objet dans un Blob ou File donc je peut alors l'ajouter à un objet FormData ?

84
demandé sur YakovL 2012-08-09 07:00:12

6 réponses

comme gengkev fait allusion dans son commentaire ci-dessus, il semble que la meilleure/seule façon de le faire est avec un appel 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();
55
répondu BrianFreud 2012-08-10 12:25:51

peut-être que quelqu'un trouve cela utile en travaillant avec React/Node/Axios. J'ai utilisé ceci pour mon téléchargement D'image Cloudinary avec react-dropzone sur L'interface utilisateur.

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

    })
6
répondu spedy 2018-02-06 11:44:10

Voir Obtenir des données BLOB de demande XHR , qui souligne que BlobBuilder ne fonctionne pas dans google Chrome, vous devrez utiliser:

xhr.responseType = 'arraybuffer';
4
répondu Michel Floyd 2017-05-23 12:03:05

Si vous afficher le fichier dans une toile de toute façon, vous pouvez également convertir la toile contenu d'un objet 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);
})
2
répondu Thilo 2014-05-07 16:31:22

solution moderne:

let blob = await fetch(url).then(r => r.blob());

l'url peut être une url d'objet ou une url normale.

2
répondu Joe 2018-09-19 16:04:41

malheureusement la réponse de @BrianFreud ne correspond pas à mes besoins, j'avais un besoin un peu différent, et je sais que ce n'est pas la réponse à la question de @BrianFreud, mais je la laisse ici parce que beaucoup de personnes sont arrivées ici avec mon même besoin. J'avais besoin de quelque chose comme " Comment obtenir un fichier ou un blob à partir d'une URL?', et la réponse correcte actuelle ne correspond pas à mes besoins parce que ce n'est pas un domaine transversal.

j'ai un site web qui consomme des images D'un stockage Amazon S3 / Azure, et là - Je stocker les objets nommés avec uniqueidentifiers:

exemple: http://****.blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf

certaines de ces images devraient être téléchargées à partir de notre interface système. Pour éviter de passer ce trafic par mon serveur HTTP, puisque cet objet N'a pas besoin de sécurité pour être accédé (sauf par le filtrage de domaine), j'ai décidé de faire une demande directe sur le navigateur de l'utilisateur et d'utiliser local traitement pour donner au fichier un vrai nom et une extension.

pour accomplir que j'ai utilisé ce grand article de Henry Algus: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax /

1. Première étape: ajouter le support binaire à 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. Deuxième étape: Faire une demande en utilisant ce type de transport.

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

Maintenant vous pouvez utiliser le Blob créé comme vous voulez, dans mon cas je veux le sauvegarder sur le disque.

3. Optionnel: Enregistrer le fichier sur l'ordinateur de l'utilisateur en utilisant FileSaver

j'ai utilisé FileSaver.js pour sauvegarder sur disque le fichier téléchargé, si vous avez besoin d'accomplir cela, s'il vous plaît utiliser cette bibliothèque javascript:

https://github.com/eligrey/FileSaver.js /

je pense ceci pour aider d'autres avec des besoins plus précis.

1
répondu Wagner Bertolini Junior 2016-12-04 11:34:04