web-dev-qa-db-ja.com

jQuery.ajax()を使用して画像を取得し、base64にデコードします

私がやりたいこと:

Basic-authで保護されたサーバーからjQuery.ajax()を使用して、イメージ(jpeg)をHTTP-GETします。画像のデータを取得したようです。バイナリである必要があります。それをbase64に変換したいのは、これをこの方法でhtmlに画像として挿入できるからです:

     $("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data));

ajax呼び出しは次のようになります。

            $.ajax({
                url: "someurltoajpeg",
                type: "GET",
                headers: {
                    "Authorization" : "Basic " +  btoa("user:pw")
                },
                xhrFields: {
                    withCredentials: true
                }
            }).done(function( data, textStatus, jqXHR ) {
                $("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data));
            }).fail(function( jqXHR, textStatus, errorThrown ) {
                alert("fail: " + errorThrown);
            });

関数base64encodeは次のようになります。

        function base64encode(binary) {
            return btoa(unescape(encodeURIComponent(binary)));
        }

ここからこの関数を取得しました: Javascriptを使用してバイナリファイルコンテンツを取得し、base64でエンコードし、Pythonを使用して逆デコードします

そこで彼はそれが彼のために働くと言います。しかし、私の場合、画像のsrc属性が変更され、いくつかの非常に長いデータが挿入されますが、その画像の非常に小さなシンボルのみが表示されます。私はその「画像」を保存することができます、それはそこにさえありません、そしてそれを開くと、私の画像ビューアはそれがjpegファイルではないと言います。これは、特定のイメージまたは同じOriginポリシーが原因のエラーではありません。誰にもこれに対する解決策がありますか?ありがとう

21
user1963987

まず、 Javascriptを使用したバイナリファイルコンテンツの取得、Pythonを使用したbase64エンコードおよびリバースデコード Ajax呼び出しに正しいmimetypeを追加します。

 $.ajax({
            url: "someurltoajpeg",
            type: "GET",
            headers: {
                "Authorization" : "Basic " +  btoa("user:pw")
            },
            xhrFields: {
                withCredentials: true
            },
            mimeType: "text/plain; charset=x-user-defined"
        }).done(function( data, textStatus, jqXHR ) {
            $("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data));
        }).fail(function( jqXHR, textStatus, errorThrown ) {
            alert("fail: " + errorThrown);
        });

次に、代わりに説明されているbase64Encode関数を使用して、btoa:

function base64Encode(str) {
        var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        var out = "", i = 0, len = str.length, c1, c2, c3;
        while (i < len) {
            c1 = str.charCodeAt(i++) & 0xff;
            if (i == len) {
                out += CHARS.charAt(c1 >> 2);
                out += CHARS.charAt((c1 & 0x3) << 4);
                out += "==";
                break;
            }
            c2 = str.charCodeAt(i++);
            if (i == len) {
                out += CHARS.charAt(c1 >> 2);
                out += CHARS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
                out += CHARS.charAt((c2 & 0xF) << 2);
                out += "=";
                break;
            }
            c3 = str.charCodeAt(i++);
            out += CHARS.charAt(c1 >> 2);
            out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
            out += CHARS.charAt(c3 & 0x3F);
        }
        return out;
    }

さようなら

28
gaetanoM

Internet Explorer 9をサポートする必要がない場合は、 FileReader AP​​I を使用してblobをデータURLに変換できます。最初の引数としてBlobを受け入れるreadAsDataURL()メソッドを提供します。 blobが読み取られるとすぐに、loadイベントが発生し、resultプロパティでデータURLが提供されます。

これは非常に安定しており、base64文字列としてカスタムエンコードを必要としないため、より少ないコードで済みます。これは、btoa( https://developer.mozilla.org/en-US/docs/ Web/API/WindowOrWorkerGlobalScope/btoa )を考慮します。

jQuery.ajax()または fetch を使用して、ファイルを Blob としてロードできます。

jQuery.ajax(url, {
  dataType: 'binary',
  xhr() {
    let myXhr = jQuery.ajaxSettings.xhr();
    myXhr.responseType = 'blob';
    return myXhr;
  }
}).then((response) => {
  // response is a Blob
  return new Promise((resolve, reject) => {
    let reader = new FileReader();
    reader.addEventListener('load', () => {
      // reader.result holds a data URL representation of response
      resolve(reader.result);
    }, false);
    reader.addEventListener('error', () => {
      reject(reader.error);
    }, false);
    reader.readAsDataURL(response);
  });
});

このサンプルコードでは Promise を使用していますが、コールバックを使用する場合も同様に機能します。

1
jelhan