当前位置:   article > 正文

http-proxy-middleware onProxyRes中文数据乱码的解决方案

http-proxy-middleware onproxyres

onProxyRes相关代码:

option.onProxyRes = function (proxyRes: any, req: any, res: any) {
        // 参考:https://www.jianshu.com/p/f8ac6e813b96
        const oriWriteHead = res.writeHead;
        const oriWrite = res.write;
        const oriEnd = res.end;
        let chunks: any = [];
        let size = 0;
        Object.assign(res, {
            writeHead: () => {},
            write: (chunk: any) => {
                chunks.push(chunk);
                size += chunk.length;
            },
            end: () => {
                let oriBuffer = Buffer.concat(chunks, size);
                console.log('buffer:', oriBuffer);
                console.log('************');
                console.log(oriBuffer.toString());
                console.log('************');
                const buffer = Buffer.concat(chunks, size); // 一定要转成buffer,buffer长度和string长度不一样
                const headers = Object.keys(proxyRes.headers)
                    .reduce((prev, key) => {
                        const value = key === 'content-length' ? buffer.length : proxyRes.headers[key];
                        return Object.assign({}, prev, {[key]: value});
                    }, {});
                oriWriteHead.apply(res, [200, headers]);
                oriWrite.call(res, buffer);
                oriEnd.call(res);
            }
        });
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

当接口返回数据不包含中文时,可以正常打印数据
在这里插入图片描述
当接口数据包含中文时,发现乱码了:
在这里插入图片描述

查询过很多解决方案都没办法解决这个问题,尝试过的解决方法:

  • 利用Buffer.concat
  • 利用iconv-lite decode

解决方案

观察接口响应header,发现了这样一个字段:

content-encoding: gzip
  • 1

瞬间就联想到是不是代理的数据是被压缩过的,于是查看node如何解压缩gzip数据,发现了zlib这个包,对接收到的chunk数据进行gunzip之后发现能够正常解析数据了。

还是前文的代码,在end函数中对oriBuffer进行处理:

let oriBuffer = Buffer.concat(chunks);
const compressBuffer = handleBuffer(oriBuffer,proxyRes.headers['content-encoding'], handleJsonResFunc);
  • 1
  • 2

handleBuffer方法如下:

const zlib = require('zlib');
/**
 * 根据Content-Encoding消息头确定解码方式,处理完数据之后再编码回去
 * @param oriBuffer
 * @param encoding 消息头中的编码格式
 * @param handleJsonResFunc
 */
function handleBuffer(oriBuffer: Buffer, encoding: string, handleJsonResFunc: Function) {
    let decodeMethod: string = '';
    let encodeMethod: string = '';
    // 编码格式介绍:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Encoding
    switch (encoding) {
        case 'gzip':
            decodeMethod = 'gunzipSync';
            encodeMethod = 'gzipSync';
            break;
        case 'deflate':
            decodeMethod = 'inflateSync';
            encodeMethod = 'deflateSync';
            break;
        case 'br':
            decodeMethod = 'brotliDecompressSync';
            encodeMethod = 'brotliCompressSync';
            break;
        default:
            break;
    }
    let decodeBuffer: Buffer = oriBuffer;
    if (decodeMethod && encodeMethod) {
        decodeBuffer = zlib[decodeMethod](oriBuffer);
    }
    // 当JSON数据转换错的时候提示前端报错
    let oriJSONRes: any;
    try {
        oriJSONRes = JSON.parse(decodeBuffer.toString());
    }
    catch (e) {
        console.error('[error]: JSON parse error! origin string: ', decodeBuffer.toString());
      // ErrorMessage为自定义的消息格式,可以忽略ErrorMessage相关代码
        oriJSONRes = new ErrorMessage({server: 'from node'}, 'Server Proxy data error');
    }
    const handledJSONRes = oriJSONRes instanceof ErrorMessage ? oriJSONRes : handleJsonResFunc(oriJSONRes);
    // 一定要转成buffer,buffer长度和string长度不一样
    const buffer = new Buffer(JSON.stringify(handledJSONRes));
    return decodeMethod && encodeMethod ? zlib[encodeMethod](buffer) : buffer;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/662484
推荐阅读
相关标签
  

闽ICP备14008679号