fetch 解析 GBK 编码 Response

通常情况,当我们使用 fetch 发送网络请求,并获得 content-typeapplication/json 的 Response 时,我们需要使用 text()json() 得到 body 的 JSON 对象。但是 text()json() 仅支持 UTF-8 编码的 response,若编码为 GBK,则得到的 JSON 对象中会存在乱码。

若想正确解析 GBK 编码的 response,我们可以先将 response 的 body 转换为 Blob 对象,再使用 FileReader.readAsText(blob[, encoding]) 通过正确的 encoding 读取为文本。

(function () {
    const readBlobAsText = (blob, encoding) => {
        return new Promise((resolve, reject) => {
            const fr = new FileReader();
            fr.onload = event => {
                resolve(fr.result);
            };

            fr.onerror = err => {
                reject(err);
            };

            fr.readAsText(blob, encoding);
        });
    };

    fetch("https://api.github.com/users/hanai", {
        "body": null,
        "method": "GET"
    }).then(res => {
        const contentType = res.headers.get('content-type');
        if (contentType !== null) {
            if (/(^|;)application\/json($|;)/i.test(contentType)) {
                const charsetMatches = contentType.match(/(^|;)charset=([^;]+)($|;)/i);
                if (charsetMatches && charsetMatches.length && charsetMatches[2]) {
                    const charset = charsetMatches[2];
                    return res.blob().then(blob => readBlobAsText(blob, charset)).then(JSON.parse);
                } else {
                    return res.json();
                }
            }
        }
    }).then(data => {
        console.log(data);
    });
}());