web-dev-qa-db-ja.com

オブジェクトURLからファイルまたはBLOBを取得する方法は?

ユーザーがドラッグ&ドロップなどの方法で画像をページにロードできるようにします。画像がドロップされると、URL.createObjectURLを使用してオブジェクトURLに変換し、画像を表示します。再利用するので、URLを取り消していません。

したがって、FormDataオブジェクトを作成して、それらの画像のいずれかを含むフォームをアップロードできるようになったら、そのオブジェクトURLを逆にしてBlobまたはFileに戻すことができる方法がありますFormDataオブジェクトに?

101
BrianFreud

上記のコメントでgengkevが言及しているように、これを行うための最良/唯一の方法は、非同期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ベースの簡単な回答を以下に示します。

65
BrianFreud

最新のソリューション:

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

URLは、オブジェクトURLまたは通常のURLです。

33
user993683

React/Node/Axiosで作業しているときに、誰かがこれを役に立つと思うかもしれません。これをUIのreact-dropzoneでCloudinary画像アップロード機能に使用しました。

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

    })
8
spedy

XHRリクエストからBLOBデータを取得する を参照してください。これは、BlobBuilderがChromeで機能しないため、使用する必要があることを示しています。

xhr.responseType = 'arraybuffer';
4
Michel Floyd

とにかくキャンバスにファイルを表示する場合、キャンバスのコンテンツを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
Thilo

残念ながら、@ BrianFreudの答えは私のニーズに合わず、少し異なるニーズがあり、@ BrianFreudの質問に対する答えではないことは知っていますが、多くの人が同じニーズでここに来たので、ここに残しています。 「URLからファイルまたはblobを取得する方法」のようなものが必要でしたが、現在の正解はクロスドメインではないため、私のニーズに合いません。

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 <[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。 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/

これは、より具体的なニーズを持つ他の人の助けになると期待しています。