Vue Axios (get file stream) set the return value type responseType: 'blob' is invalid

1, Demand

For vue project, it is required to obtain the file stream transmitted by the third-party platform through the interface without downloading. After obtaining, it is converted into a file and automatically uploaded to the media database of the current platform.

2, Development process

After Baidu, we found the format to convert the file into blob file stream, and then convert the blob into file file

let blob = new Blob([data]);//data is a file stream (in string format, I'm not aware of the problem of garbled code at this time)
let file = new File([blob], row[1], {type:"audio/mpeg"});

Integrate it into your own code. Because responseType: "blob" is set, the returned data is the blob file stream, which does not need to be converted, as follows:

//api file
download(id){
	return request({
	  url: '/media/getMedia?id='+id,//Here, the current platform listening interface is used for simulation,
	  method: 'get',
      responseType: "blob",  //Required
	})
},
//In the jax File, the url is transferred to blob and File, and then the File is uploaded
autoDownUpLoad(row){
    console.log(row)//row[0]-name row[7]-id row[8] - path
    this.$myfun.show_Loading()

    this.$api.download(row[7]).then(data => {
        var file = new File([data], row[1], {type:"audio/mpeg"});
        console.log(data,file)
        // Upload interface
        const formData = new FormData()
        formData.append('filefield', file)
        formData.append('name', row[0]);
        axios.post('/media/addAudio', formData, {
            headers: {
                'Content-Type': 'multipart/form-data',
                'Referer_':location.hash.substr(1)
            }
        }).then(res => {
            if (res.data.success) {
                this.$message.success('Added successfully');
            }else{
                this.$message.error(res.data.message)
            }
            this.getAjax()
            this.$myfun.close_Loading()
        })
    })
}

The upload times were wrong. After investigation, it was found that the uploaded audio file could not be played, so the problem has been investigated all the time. F12 a look, the browser does not get Blob type, but a string of garbled code.

We don't understand what this is, and we don't know if it's a random code. We only know that it's a string. Therefore, it's useless to transfer all kinds of Baidu to blob. What responseType: "blob" and what new Blob([data]), and it's clear that the blob file stream will be returned after adding responseType: "blob". Why is mine still a string?
So I started Baidu responseType:'blob' is invalid and found a big man. Here is his blog link: Vue Axios (download file stream) sets the problem that the return value type responseType:'blob' is invalid

3, Cause

----------"mock module will affect the native ajax request, making the blob type returned by the server become garbled"--------
You can see that during the initialization of mockjs in overrideMimeType(), the responseType is set for the intercepted response: ''

// Initialize Response related properties and methods
Util.extend(MockXMLHttpRequest.prototype, {
   responseURL: '',
   status: MockXMLHttpRequest.UNSENT,
   statusText: '',
   // https://xhr.spec.whatwg.org/#the-getresponseheader()-method
   getResponseHeader: function(name) {
       // Native XHR
       if (!this.match) {
           return this.custom.xhr.getResponseHeader(name)
       }

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

       // Intercept 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
})

4, Summarize the solutions of the bosses:

1. Don't use mockjs. Find the place where mockjs is introduced and comment out import and require
2. Change the source code
dist/mock.js
About 8683 lines, plus one line of code

this.custom.xhr.responseType = this.responseType


3. But outrageously, my project mock JS is in index HTML, once commented out, use mock The file of mock (URL, 'get', (RES) = > {}) will report an error, so we looked at the error report. Mock is undefined. At this time, we should understand that if it is not introduced, of course, an error will be reported. Therefore, we commented out the file that uses mockjs to simulate the request back-end interface to obtain data, that is, we use mock Mock (URL, 'get', (RES) = > {}) file, test it, and finally it's done.

Keywords: Front-end

Added by zplits on Sun, 26 Dec 2021 04:17:26 +0200