Javascript 如何从couchdb附件转换base64中的二进制数据

Javascript 如何从couchdb附件转换base64中的二进制数据,javascript,couchdb,binaryfiles,Javascript,Couchdb,Binaryfiles,我尝试从couchdb服务器获取二进制数据。但是我可以用它们。响应包含一个表示二进制数据的字符串,但如果我尝试使用函数btoa在base64中编码,函数会给出以下错误: 未捕获的InvalidCharacterError:“btoa”失败:要编码的字符串包含拉丁1范围以外的字符 我知道我可以直接用base64编码数据,但我不想要 $.ajax({ url: "http://localhost:5984/testdb/7d9de7a8f2cab6c0b3409d449500

我尝试从couchdb服务器获取二进制数据。但是我可以用它们。响应包含一个表示二进制数据的字符串,但如果我尝试使用函数btoa在base64中编码,函数会给出以下错误:

未捕获的InvalidCharacterError:“btoa”失败:要编码的字符串包含拉丁1范围以外的字符

我知道我可以直接用base64编码数据,但我不想要

    $.ajax({
        url: "http://localhost:5984/testdb/7d9de7a8f2cab6c0b3409d4495000e3f/img",
        headers: {
                Authorization: 'Basic ' + btoa("name:password"),
        },
        success: function(data){
            /*console.log(JSON.parse(jsonData));
            console.log(imageData);*/
            document.getElementById("immagine").src = "Data:image/jpg;base64," + btoa(data);
            console.log(data);
        }
    });

有什么想法吗?

首先要知道Base64字符串中的每个字符

表示一个数字,特别是从
0
63
。接下来,考虑这个数字范围是你可以用“代码>6”/代码>位写的所有数字,并且我们通常认为二进制数据是字节的,即<代码> 8 位长。

现在我们可以得出结论,我们要实现的转换是
8
位整数到
6
位整数,看起来有点像这样

xxxxxx xxyyyy yyyyzz zzzzzz
其中每个字母描述位所在的字节,空格描述
6
位整数之间的中断

一旦我们有了
6
位号,我们可以简单地转换为字符,最后添加
=
符号,如果我们需要指示字节数不是
3
的倍数(而且它们不是简单的
0

那么我们如何做到这一点呢

var arr8 = 'foobar'; // assuming binary string

var i, // to iterate
    s1, s2, s3, s4, // sixes
    e1, e2, e3, // eights
    b64 = ''; // result
// some code I prepared earlier
for (i = 0; i < arr8.length; i += 3) {
    e1 = arr8[i    ];
    e1 = e1 ? e1.charCodeAt(0) & 255 : 0;
    e2 = arr8[i + 1];
    e2 = e2 ? e2.charCodeAt(0) & 255 : 0;
    e3 = arr8[i + 2];
    e3 = e3 ? e3.charCodeAt(0) & 255 : 0;
    // wwwwwwxx xxxxyyyy yyzzzzzz
    s1 =                     e1 >>> 2 ;
    s2 = ((e1 &  3) << 4) + (e2 >>> 4);
    s3 = ((e2 & 15) << 2) + (e3 >>> 6);
    s4 =   e3 & 63                    ;
    b64 += chars[s1] + chars[s2];
    if (arr8[i + 2] !== undefined)
        b64 += chars[s3] + chars[s4];
    else if (arr8[i + 1] !== undefined)
        b64 += chars[s3] + '=';
    else
        b64 += '==';
}
// and the result
b64; // "Zm9vYmFy"
var arr8='foobar';//假设二进制字符串
var i,//进行迭代
s1、s2、s3、s4、//六
e1、e2、e3、//八
b64=“”;//后果
//我之前准备的一些代码
对于(i=0;i>>2;
s2=((e1&3)>>4);
s3=((e2&15)>>6);
s4=e3&63;
b64+=字符[s1]+字符[s2];
如果(arr8[i+2]!==未定义)
b64+=字符[s3]+字符[s4];
else if(arr8[i+1]!==未定义)
b64+=chars[s3]+'=';
其他的
b64+='='=';
}
//结果呢
b64;//“Zm9vYmFy”

我使用的btoa功能运行良好。字符串名称:password的编码正确。我认为问题在于我从couchdb获得的数据server@Morris
btoa
不是二进制安全的,因此您需要编写自定义oneok。但是,您的代码不起作用。我用您的代码获得的base64与原始图像不同。
var arr8 = 'foobar'; // assuming binary string

var i, // to iterate
    s1, s2, s3, s4, // sixes
    e1, e2, e3, // eights
    b64 = ''; // result
// some code I prepared earlier
for (i = 0; i < arr8.length; i += 3) {
    e1 = arr8[i    ];
    e1 = e1 ? e1.charCodeAt(0) & 255 : 0;
    e2 = arr8[i + 1];
    e2 = e2 ? e2.charCodeAt(0) & 255 : 0;
    e3 = arr8[i + 2];
    e3 = e3 ? e3.charCodeAt(0) & 255 : 0;
    // wwwwwwxx xxxxyyyy yyzzzzzz
    s1 =                     e1 >>> 2 ;
    s2 = ((e1 &  3) << 4) + (e2 >>> 4);
    s3 = ((e2 & 15) << 2) + (e3 >>> 6);
    s4 =   e3 & 63                    ;
    b64 += chars[s1] + chars[s2];
    if (arr8[i + 2] !== undefined)
        b64 += chars[s3] + chars[s4];
    else if (arr8[i + 1] !== undefined)
        b64 += chars[s3] + '=';
    else
        b64 += '==';
}
// and the result
b64; // "Zm9vYmFy"