You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中Base64转JSON遇字符间隔问题求助

问题描述

我有一段如下的Base64编码,希望将其转换为可用的JSON,但尝试后无法正常使用转换后的结果:

const base64 = "H4sIAAAAAAAEAO2b0W6CMBSGz6MsXm+JUKi6N9gzLLsw4jYTo0bJbpa9+44Ig0J7kBW0PSENNG2B9vtjw09PfYVvmMAGEjw/QwiPmKdYTmEL66xuAics7eGI5QcI4AmPSXbdAZZZ7Q7bX/InBFlLeYdaf37mFx7bSl2C5ROs8OoNPvHc9x6feOk5BAFR3tsK65O/MQmQEGP+g21VAgFzI8O5hx183Gz0zT5VBrW9SbLwkiTQsEQw9ZQl1NKY54nrNJf51CQS7IgidkQxOyLJjmjGjsjP9ylF5Ot71UQUe/x2NREFzIgkO88g2XkGyc4zSHaeQXrqGUTOVD3r+Xx0ECpXF1rKXaj382OnfMi92dX+h1ViZvAvByUtG+lYS+ta2ikpraX7qLnEcgLveX4530Jhyk+V95cjK/N7//76UEylovXTqUd5t1G9NvUonziq16Ye5UlH9drUo/zvqF6bepTXHtWj1Ztf6W3/q16x6nOdfqGH+l3nj0f9TPoNO3sj9vpRX+Kjfu36Detcivg4X/2G9S789Rv2q63YacJXv2G/27jrZ1avupcqJBQKe9WnWBtqcoss8qGPw9lErfodf1+RRZuolZtENlErN4lsolZuEtlErdwksolTuUlks9PFTSKbnS4uEkmrnS5uEtnsdHGRaE4S2fvG/pldco2LgVe9RAf1xA3UW8Entm6zUdS1CHC26+e7mW/R6as2aiXUjVk/UupXH2f7KNvXw6ed1oRi6xkd5f+heINfmSW/7QgyAAA="

补充说明:该数据来自SQL Server数据库,类型为varBinary(Max)。

已尝试步骤
  • 使用atob转换为字符串:
    let convertString = atob(base64);
    
  • 将字符串转换为ArrayBuffer:
    let arrayBuffer = new ArrayBuffer(convertString.length);
    let uint8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < convertString.length; i++) {
        uint8Array[i] = convertString.charCodeAt(i);
    }
    
  • 使用pako库解压后,得到的字符间存在空格,无法正常解析为JSON:
    let inflatedData = pako.inflate(uint8Array, { to: 'string' });
    console.log(inflatedData)
    
解决方法

问题出在解压后的原始字节采用UTF-16LE编码(SQL Server的varBinary(Max)存储Unicode字符串时,通常用UTF-16LE格式),但pako默认以UTF-8解码,导致字符被错误解析,出现间隔空格。

正确处理步骤如下:

  1. 解码Base64到Uint8Array(可使用更简洁的写法):

    const uint8Array = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
    
  2. 用pako解压获取原始字节数组:
    不要直接指定to: 'string',先获取解压后的Uint8Array:

    const decompressedBytes = pako.inflate(uint8Array);
    
  3. 用UTF-16LE编码解码字节数组为字符串:
    使用TextDecoder指定编码格式,将解压后的字节转换为正确的字符串:

    const decoder = new TextDecoder('utf-16le');
    const jsonString = decoder.decode(decompressedBytes);
    
  4. 解析为JSON对象:

    const jsonData = JSON.parse(jsonString);
    console.log(jsonData);
    

完整代码示例:

const base64 = "H4sIAAAAAAAEAO2b0W6CMBSGz6MsXm+JUKi6N9gzLLsw4jYTo0bJbpa9+44Ig0J7kBW0PSENNG2B9vtjw09PfYVvmMAGEjw/QwiPmKdYTmEL66xuAics7eGI5QcI4AmPSXbdAZZZ7Q7bX/InBFlLeYdaf37mFx7bSl2C5ROs8OoNPvHc9x6feOk5BAFR3tsK65O/MQmQEGP+g21VAgFzI8O5hx183Gz0zT5VBrW9SbLwkiTQsEQw9ZQl1NKY54nrNJf51CQS7IgidkQxOyLJjmjGjsjP9ylF5Ot71UQUe/x2NREFzIgkO88g2XkGyc4zSHaeQXrqGUTOVD3r+Xx0ECpXF1rKXaj382OnfMi92dX+h1ViZvAvByUtG+lYS+ta2ikpraX7qLnEcgLveX4530Jhyk+V95cjK/N7//76UEylovXTqUd5t1G9NvUonziq16Ye5UlH9drUo/zvqF6bepTXHtWj1Ztf6W3/q16x6nOdfqGH+l3nj0f9TPoNO3sj9vpRX+Kjfu36Detcivg4X/2G9S789Rv2q63YacJXv2G/27jrZ1avupcqJBQKe9WnWBtqcoss8qGPw9lErfodf1+RRZuolZtENlErN4lsolZuEtlErdwksolTuUlks9PFTSKbnS4uEkmrnS5uEtnsdHGRaE4S2fvG/pldco2LgVe9RAf1xA3UW8Entm6zUdS1CHC26+e7mW/R6as2aiXUjVk/UupXH2f7KNvXw6ed1oRi6xkd5f+heINfmSW/7QgyAAA=";

// 解码Base64到Uint8Array
const uint8Array = Uint8Array.from(atob(base64), c => c.charCodeAt(0));

// pako解压获取原始字节
const decompressedBytes = pako.inflate(uint8Array);

// UTF-16LE解码为字符串
const decoder = new TextDecoder('utf-16le');
const jsonString = decoder.decode(decompressedBytes);

// 解析为JSON
const jsonData = JSON.parse(jsonString);
console.log(jsonData);

错误原因说明

pako.inflate(..., { to: 'string' })默认使用UTF-8解码字节,但原始数据是UTF-16LE编码(每个字符占2字节)。UTF-8解析时会把每个字节当成独立字符,导致原本的单字符被拆成两个,表现为字符间的空格(实际是错误编码的不可见字符)。

内容的提问来源于stack exchange,提问作者davood beheshti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:12:05