blob下载--返回数据乱码问题

blob下载返回数据乱码问题

之前介绍过下载,在使用blob方式进行下载的时候,遇到返回的数据为乱码

服务端需要设置为response.setContentType(“application/octet-stream”),但是这个值不一定非设置成"application/octet-stream",当下载文件类型不止一种时需要设置为该值,否则设置为对应的类型即可,例如:
response.setContentType(“application/vnd.ms-excel;charset=utf-8”);

正常情况下,blob返回的数据类型,

blob下载--返回数据乱码问题_第1张图片
但是返回乱码时的返回数据情况为:

blob下载--返回数据乱码问题_第2张图片
因为之前明明是有过可以正常下载的,证明确实不是ContentType的问题,最后发现是由于mockjs导致。

比较发现下面乱码中的request是MockXMLHttpRequest,展开查看:

blob下载--返回数据乱码问题_第3张图片
发现responseType为‘’,这也是导致blob下载失败的根本原因,因为blob我们需要设置的responseType为’blob’

而关于responseType为何被重新设置,查看mock源码发现有这么一段代码:

// 初始化 Response 相关的属性和方法
Util.extend(MockXMLHttpRequest.prototype, {
    responseURL: '',
    status: MockXMLHttpRequest.UNSENT,
    statusText: '',
    // https://xhr.spec.whatwg.org/#the-getresponseheader()-method
    getResponseHeader: function(name) {
        // 原生 XHR
        if (!this.match) {
            return this.custom.xhr.getResponseHeader(name)
        }

        // 拦截 XHR
        return this.custom.responseHeaders[name.toLowerCase()]
    },
    // https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method
    // http://www.utf8-chartable.de/
    getAllResponseHeaders: function() {
        // 原生 XHR
        if (!this.match) {
            return this.custom.xhr.getAllResponseHeaders()
        }

        // 拦截 XHR
        var responseHeaders = this.custom.responseHeaders
        var headers = ''
        for (var h in responseHeaders) {
            if (!responseHeaders.hasOwnProperty(h)) continue
            headers += h + ': ' + responseHeaders[h] + '\r\n'
        }
        return headers
    },
    overrideMimeType: function( /*mime*/ ) {},
    responseType: '', // '', 'text', 'arraybuffer', 'blob', 'document', 'json'
    response: null,
    responseText: '',
    responseXML: null
})

发现在mock中初始化 Response 会重置responseType的值,而下载中是需要设置 responseType: 'blob’的,
因此需要注释掉引入mock的代码,或者设置引入mock的开关为关,例如

mockjs的引入会导致 交互的responseType为‘’,所以在生产环境,或其他需要下载的环境不要引入mockjs

/**
 * 配置是否开启mock功能
 * @type {boolean}
 */
const MOCK_SWITCH = process.env.NODE_ENV === 'production' ? false : true;


/**
 * 引入 mock 数据
 * @constructor
 */
let MOCK_DATA = () => {
    if (MOCK_SWITCH) {
        require("../mock/mock");
    }
}

你可能感兴趣的:(前端模块开发,javascript)