使用 jQuery.ajax() 获取图像并将其解码为 base64

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19124701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:14:00  来源:igfitidea点击:

Get Image using jQuery.ajax() and decode it to base64

jqueryajaximagebinarybase64

提问by user1963987

What i want to do:

我想做的事:

HTTP-GET an image (jpeg) using jQuery.ajax() from a basic-auth secured server. it seems like i get some data of the image, it must be binary. i want to convert that to base64, because then i can insert this as an image in my html this way:

使用 jQuery.ajax() 从基本认证安全服务器 HTTP-GET 图像 (jpeg)。好像我得到了一些图像数据,它必须是二进制的。我想将其转换为 base64,因为这样我就可以将它作为图像插入到我的 html 中:

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

the ajax call looks like this:

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

the function base64encode looks like this:

函数 base64encode 如下所示:

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

i got this function from here: Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Python

我从这里得到了这个函数: Retrieving binary file content using Javascript, base64 encoding it and reverse-decode it using Python

there he says that it works for him. but in my case the src attribute of my image is changed, and some very long data is inserted, but only the very small symbol for that an image should be there appears. i can save that "image", thats not even there, and when i open it, my image viewer says, that it is not a jpeg file. this is not an error caused by the specific image or by the same origin policy. has anyone a solution to this? thanks

他说这对他有用。但在我的情况下,我的图像的 src 属性发生了变化,并插入了一些很长的数据,但只出现了图像应该存在的非常小的符号。我可以保存那个“图像”,那甚至没有,当我打开它时,我的图像查看器说,它不是一个 jpeg 文件。这不是由特定图像或同源策略引起的错误。有没有人解决这个问题?谢谢

回答by gaetanoM

First of all, according to Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Pythonadd the correct mimetype to the Ajax call:

首先,根据Retrieving binary file content using Javascript,base64 对其进行编码并使用 Python 对其进行反向解码,将正确的 mimetype 添加到 Ajax 调用中:

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

Then use base64Encode function described instead then the btoa:

然后使用描述的 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;
    }

bye

再见

回答by jelhan

If you don't have to support Internet Explorer 9, you could use FileReaderAPIto convert a blob to a data URL. It provides a readAsDataURL()method that accepts a Blob as first argument. As soon as the blob is read, it fires a loadevent and provides the data URL on resultproperty.

如果您不必支持 Internet Explorer 9,则可以使用FileReaderAPI将 blob 转换为数据 URL。它提供了一个readAsDataURL()接受 Blob 作为第一个参数的方法。一旦读取 blob,它就会触发一个load事件并在result属性上提供数据 URL 。

This is way more stable and requires less code since it does not require custom encoding as base64 string, which is a complex task taking limitations of btoa(https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa) into account.

这是更稳定的方式并且需要更少的代码,因为它不需要自定义编码为 base64 字符串,这是一项复杂的任务,受 btoa 的限制(https://developer.mozilla.org/en-US/docs/Web/API/ WindowOrWorkerGlobalScope/btoa) 考虑在内。

You could use jQuery.ajax()or fetchto load the file as a Blob.

您可以使用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);
  });
});

This example code is using Promisebut it would work similar if using callbacks.

此示例代码使用Promise,但如果使用回调,它的工作方式类似。