Axios 接收文件

159 阅读1分钟

今天遇到一前端问题。axios 导出后台 xls 文件出现乱码。

多会儿没写发现前端了,发现是没指定响应类型时,axios 默认把响应内容包成字符串,即 type(res.data) = 'string',直接保存字符串形式存储的二进制就出错了。

解决:指定响应类型为 Blob,那么 axios 会把响应包装为 Blob 类型。同时需要在处理响应时根据 res.data.type 判断是否为 blob 类型再继续处理。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <button @click="down">download</button>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    new Vue({
        el: '#app',
        methods: {
            down() {
                var http = axios.create({
                    baseURL: 'http://t.t.cn:808/',
                    timeout: 5000,
                    headers: { 'X-Auth-Token': 'b59a2f6c-41ec-bcf2-4cce326b22b2' }
                })
                
                // 请求,指定响应为 blob 类型
                http.get('/xls/export/afaIIdx1ag3ex', { responseType: 'blob' })
                    .then(res => {
                        // 判断响应是否为 json 类型
                        if (res.data && res.data.type && res.data.type == 'application/json') {
                            (new Response(res.data)).text().then(
                                res => {
                                    console.log(JSON.parse(res).msg);
                                }
                            )
                        } else {
                            const link = document.createElement('a')
                            link.href = window.URL.createObjectURL(new Blob([res.data]))
                            document.body.appendChild(link)
                            link.download = 'xxx导出.xls'
                            link.click()
                        }
                    }).catch(e => {
                        console.log("error, ", e);
                    })
            }
        }
    })
</script>

</html>