简体   繁体   中英

How to parse into base64 string the binary image from response?

I want to parse the requested image from my REST API into base64 string.

在此处输入图片说明

Firstly... I thought, it would be easy, just to use window.btoa() function for this aim.

When I try to do it in such part of my application:

.done( function( response, position ) {
    var texture = new Image();
    texture.src = "data:image/png;base64," + window.btoa( response ); 

I've got the next error: Uncaught InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

As I read here: javascript atob returning 'String contains an invalid character'

The issue occurs because of newlines in the response and that's why window.btoa() failed. Any binary image format of course will have newlines... But as from the link above the suggestion was to remove/replace those characters - is a bad suggestion for me, because if to remove/replace some characters from binary image it just will be corrupted.

Of course, the possible alternatives relate to the API design: - to add some function, which return base64 representation - to add some function, which return url to the image

If I won't repair it, I shall return base64 representation from the server, but I don't like such a way.

Does exist some way to solve my problem with the handling binary image from response, as it's shown above in the part of screenshot, doesn't it?

I think part of the problem you're hitting is that jQuery.ajax does not natively support XHR2 blob/arraybuffer types which can nicely handle binary data (see Reading binary files using jQuery.ajax ).

If you use a native XHR object with xhr.responseType = 'arraybuffer' , then read the response array and convert it to Base64, you'll get what you want.

Here's a solution that works for me:

 // http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/ function fetchBlob(uri, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', uri, true); xhr.responseType = 'arraybuffer'; xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; if (callback) { callback(blob); } } }; xhr.send(); }; fetchBlob('https://i.imgur.com/uUGeiSFb.jpg', function(blob) { // Array buffer to Base64: var str = btoa(String.fromCharCode.apply(null, new Uint8Array(blob))); console.log(str); // Or: '<img src="data:image/jpeg;base64,' + str + '">' });

https://jsfiddle.net/oy1pk8r3/2/

Produces base64 encoded console output: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAIBAQIBAQICAgICAgICAw.....

instead of looping through the blob with _arrayBufferToBase64(), use apply() to do the conversion, it's 30 times faster in my browser and is more concise

 // http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/ function fetchBlob(uri, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', uri, true); xhr.responseType = 'arraybuffer'; xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; if (callback) { callback(blob); } } }; xhr.send(); }; fetchBlob('https://i.imgur.com/uUGeiSFb.jpg', function(blob) { var str = String.fromCharCode.apply(null, new Uint8Array(blob)); console.log(str); // the base64 data: image is then // '<img src="data:image/jpeg;base64,' + btoa(str) + '" />' });

Im guessing to use escape on the string before you pass it to the function, without the API call I can't test myself.

test

encodeURI("testñ$☺PNW¢=")

returns

"test%C3%B1$%E2%98%BAPNW%C2%A2="

It just escapes all the characters, it should escape all the illegal characters in the string

test

encodeURI("¶!┼Æê‼_ðÄÄ┘Ì+\+,o▬MBc§yþó÷ö")

returns

"%C2%B6!%E2%94%BC%C3%86%C3%AA%E2%80%BC_%C3%B0%C3%84%C3%84%E2%94%98%C3%8C++,o%E2%96%ACMBc%C2%A7y%C3%BE%C3%B3%C3%B7%C3%B6"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

The issue you're encountering is that the response is being considered a Unicode String. See the section on Unicode Strings here: window.btoa

Several solutions are offered in this post

Long story short this looks like someone read the image with readAsText() which mangles ("interprets") binary into utf8, instead of utf16. You need to get the server to return the data in arraybuffer or blob format ideally, or even base64, these preserve binary.

Long version with snippet. (those question marks symbols in the snippet show the lost information, compare it to the binary where they are not question marks in utf16): https://stackoverflow.com/a/56523118/2962797

Try this on its working well . please try once. @user2402179

  $.ajax({
    type: 'GET',
    url: baseUrl",
    dataType: 'binary',
    xhr() {
      let myXhr = jQuery.ajaxSettings.xhr();
      myXhr.responseType = 'blob';
      return myXhr;
    },
    headers: {'Authorization': 'Bearer '+token}      
    
}).then((response) => {
    // response is a Blob
    return new Promise((resolve, reject) => {
      let reader = new FileReader();
      reader.addEventListener('load', () => {
        $('#theDiv').append('<img src="' +reader.result+ '" />')
        resolve(reader.result);
      }, false);
      reader.addEventListener('error', () => {
        reject(reader.error);
      }, false);
      reader.readAsDataURL(response);
    });
  });

Base 64 Image 数据对我有用

<img src="data:image/png;base64,' + responce + '" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM