【问题标题】:Convert binary data to base64 with javascript使用javascript将二进制数据转换为base64
【发布时间】:2012-06-14 12:17:19
【问题描述】:

HTML5 使您能够在本地存储数据,我认为这很棒。例如,您可以使用它:

        var store = window.localStorage;
        store.setItem('foo', "hellow world");
        var test = store.getItem('foo');
        // test should = "hellow world"

在 html 中,您可以通过将其来源设置为动态显示图像:

     "data:image/jpg;base64," + (base64string)

所以我的问题是如何将二进制数据转换为 base64 字符串,以便我可以利用 html5 本地存储?

例如,如果可以的话,那就太好了:

$.ajax({
   url: 'someImage.png',
   type: 'POST',
   success: function (r) {

                // here I want to convert r to a base64 string !
                // r is not binary so maybe I have to use a different approach
                var data = ConvertToBase64(r);



                document.getElementById("img").src = "data:image/png;base64," + data;
            },
});

我知道我可以通过使用 html5 将图像包裹在画布周围然后将其转换为 base64string 来解决这个问题。我也可以在服务器上创建一个特定的服务,该服务将发送该图像的 base64 字符串数据 (someImage.aspx)。我只想知道是否可以从服务器检索二进制数据并将其转换为base64 字符串。

【问题讨论】:

标签: javascript html base64


【解决方案1】:

试试btoa函数:

   var data = btoa(r);

【讨论】:

  • 不幸的是,这不适用于二进制数据:未捕获的 InvalidCharacterError:无法在 'Window' 上执行 'btoa':要编码的字符串包含 Latin1 范围之外的字符。"
  • 我的 Chrome 不同意。或者为什么它会给我这个错误信息?是因为我的字符串以某种方式被解释为 UTF-8 吗?
  • @BastianVoigt 因为你有普通的 unicode 字符串而不是二进制字符串
  • @Esailija 以及如何使用普通的 unicode 字符串?我的意思是我正在尝试将其保存为 jpeg,但运气不佳:(
  • 似乎图像文件中通常包含 unicode 字符串以及二进制数据。所以这个答案可能不适用于图片
【解决方案2】:

使用FileReader 将您的图像编码为数据 URL:

jQuery.ajax({...})
.done(function (r) {
  var reader = new FileReader(
  reader.onload = (function(self) {
    return function(e) {
      document.getElementById("img").src = e.target.result;
    }
  })(this);
  reader.readAsDataURL(new Blob([r]));
});

【讨论】:

  • 效果很好!我将它与req = new XMLHttpRequest() 结合使用,我必须设置req.responseType = 'blob' 才能使其工作。 blob 数据位于req.response
  • 只是添加,来自e.target.result的字符串内容将以文件类型开头,例如data:application/pdf;base64, 然后是实际的 base64 字符串。所以,如果你需要纯base64,用逗号分隔,取第二部分。
【解决方案3】:

为防止出现“InvalidCharacterError”错误,您需要这样做:

var base64EncodedStr = btoa(unescape(encodeURIComponent(rawData)));

【讨论】:

  • 不推荐使用的 unescape() 方法计算一个新字符串,其中十六进制转义序列被替换为它所代表的字符。转义序列可能由转义之类的函数引入。由于不推荐使用 unescape(),请改用 decodeURI() 或 decodeURIComponent。
  • 使用 decodeURI 和 decodeURIComponent 会导致“错误:无法在 'Window' 上执行 'btoa':要编码的字符串包含 Latin1 范围之外的字符”,所以我坚持使用 unsecape。
  • 使用decodeURI 代替已折旧的unescapedeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 在我的情况下,问题是 unescape 出于某种原因导致无效图像(不渲染)并且移动到 decodeURI 可能是正确的举动,因为这让我马上回来对于btoa() 的问题,这会导致不可避免的错误:“无法在'Window' 上执行'btoa':要编码的字符串包含Latin1 范围之外的字符。”
  • 由于这个问题不是专门针对图像的,我已经在这里解决了我的解决方案(它依赖于String.fromCharCode 来修复btoa() 错误):stackoverflow.com/a/66823987/899075
【解决方案4】:

这是一个老问题,但找不到更好的答案,所以我写下了这个函数。它会将 Uint8Array 直接转换为 Base64,而不会将其转换为 base64 之前的字符串。希望它会对某人有所帮助。

var encoder = new TextEncoder("ascii");
var decoder = new TextDecoder("ascii");
var base64Table = encoder.encode('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=');
function toBase64(dataArr){
    var padding = dataArr.byteLength % 3;
    var len = dataArr.byteLength - padding;
    padding = padding > 0 ? (3 - padding) : 0;
    var outputLen = ((len/3) * 4) + (padding > 0 ? 4 : 0);
    var output = new Uint8Array(outputLen);
    var outputCtr = 0;
    for(var i=0; i<len; i+=3){              
        var buffer = ((dataArr[i] & 0xFF) << 16) | ((dataArr[i+1] & 0xFF) << 8) | (dataArr[i+2] & 0xFF);
        output[outputCtr++] = base64Table[buffer >> 18];
        output[outputCtr++] = base64Table[(buffer >> 12) & 0x3F];
        output[outputCtr++] = base64Table[(buffer >> 6) & 0x3F];
        output[outputCtr++] = base64Table[buffer & 0x3F];
    }
    if (padding == 1) {
        var buffer = ((dataArr[len] & 0xFF) << 8) | (dataArr[len+1] & 0xFF);
        output[outputCtr++] = base64Table[buffer >> 10];
        output[outputCtr++] = base64Table[(buffer >> 4) & 0x3F];
        output[outputCtr++] = base64Table[(buffer << 2) & 0x3F];
        output[outputCtr++] = base64Table[64];
    } else if (padding == 2) {
        var buffer = dataArr[len] & 0xFF;
        output[outputCtr++] = base64Table[buffer >> 2];
        output[outputCtr++] = base64Table[(buffer << 4) & 0x3F];
        output[outputCtr++] = base64Table[64];
        output[outputCtr++] = base64Table[64];
    }
    
    var ret = decoder.decode(output);
    output = null;
    dataArr = null;
    return ret;
}

【讨论】:

    【解决方案5】:
    //dataArr is a Uint8Array        
    function toBase64(dataArr){
                return btoa(dataArr.reduce((data, val)=> {
                     return data + String.fromCharCode(val);
                }, ''));
            }
    

    【讨论】:

    • 这似乎是一个很好的答案,简洁明了,它处理了我的问题...... 无法在“窗口”上执行“btoa”:要编码的字符串包含拉丁语1之外的字符范围
    【解决方案6】:

    适用于现代浏览器的公平简单的解决方案

    fetch('https://picsum.photos/536/354', {
        method: 'GET',
    })
    .then((data) => {
        // IMP to convert your json or other response to blob ( for this you have to check your api response is file / binary 
        return data.blob()
    })
    .then((data) => {
        var reader = new FileReader();
        reader.onload = function() {                         
            var b64 = reader.result
            console.log("This is base64", b64)
            document.getElementById("imagetoShow").src = b64
        }
        reader.readAsDataURL(data)
    })
    .catch((error) => {
        error.text().then( errorMessage => {
            console.log(errorMessage)
        })
    })
    &lt;image src="" width="200" height="200" id="imagetoShow"/&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-26
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 2017-08-29
      相关资源
      最近更新 更多