vue3.x 接收后端文件流下载文件(六)

前提:基于上一篇文章进行学习
1、后端搭建
使用nodejs、 express 框架搭建后端服务器

  • 启动文件app.js
var express = require("express");
var http = require("http");
var fs = require('fs');
var app = express();

// 静态资源托管工具

app.use(express.static("./static"));

app.get("/", function(req, res) {
  res.send("Hello");
})

app.post("/file/download", async function(req, res) {
  res.setHeader('Access-Control-Allow-Origin','*');
  function read() {
    return new Promise((resolve, reject) => {
      fs.readFile('./static/cat.jpg', function(err, data) {
        resolve(data);
        reject(err);
      })
    })
  }
  let data = await read();
  res.send(data);
})

var httpServer = http.createServer(app);
const PORT = 3000;
const HOSTNAME = '0.0.0.0';
httpServer.listen(PORT, HOSTNAME, function() {
  console.log('Server is running on http://' + HOSTNAME + ':%s', PORT);
})

静态资源文件目录static, 放置一张图片用于测试

  • 启动服务器
node app.js

2、前端vue功能实现

  • 页面
<template>
  <div>
    <el-button type="primary" @click="downloadFile" plain>下载</el-button>
  </div>
</template>

<script>
import FileModel from '@/api/file.js';
import { dataToFile } from '@/utils/common/common.js';


export default {
  name: 'fileDownLoad',
  setup() {
    const downloadFile = () => {
      FileModel.fileExport().then(res => {
        let params = {
          data: res,
          fileName: '1.jpg',
          type: 'application/octet-stream'
        }
        dataToFile(params);
      }).catch(err => {
        console.log(err);
      })
    }

    return {
      downloadFile
    }
  }
}
</script>
  • api下的file.js
import { exportFile } from "@/utils/http";

export default {
  // 文件下载导出
  fileExport(data = {}) {
    return exportFile("/api/file/download", data);
  }
};
  • 调整接口封装逻辑utils/http.js
import axios from "./request";

function get(url, params) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params
    }).then(response => {
      resolve(response.data)
    }, error => {
      reject(error)
    })
  })
}

function post(url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, params
    ).then(response => {
      resolve(response.data)
    }, error => {
      reject(error)
    })
  })
}

function exportFile(url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, params, {
      responseType: 'blob'
    }).then(response => {
      resolve(response)
    }, error => {
      reject(error)
    })
  })
}

export {
  get,
  post,
  exportFile
}

utils/request.js

import axios from "axios";

// 创建axios 实例
const service = axios.create({
  baseURL: "/", // api的base_url
  timeout: 10000 // 请求超时时间
});

// request 拦截器
service.interceptors.request.use(
  config => {
    // config.headers.Authorization = getCookie("Authorization");
    // 这里可以自定义一些config 配置
    return config;
  },
  error => {
    //  这里处理一些请求出错的情况
    Promise.reject(error);
  }
);

// response 拦截器
service.interceptors.response.use(
  response => {
    const res = response.data;
    // 这里处理一些response 正常放回时的逻辑
    return res;
  },
  error => {
    // 这里处理一些response 出错时的逻辑
    return Promise.reject(error);
  }
);

export default service;

此时请求接口,看到后台返回的文件流
vue3.x 接收后端文件流下载文件(六)

  • 处理文件流,对此功能进行了封装utils/common/common.js
    使用blob、配合a标签的download属性实现文件的下载
    common.js
function dataToFile(params) {
  let type = params.type
  let fileName = params.fileName
  let data = params.data;
  // 兼容 IE
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(new Blob([data]), fileName)
  } else {
    // 非IE 浏览器
    const url = window.URL.createObjectURL(new Blob([data], { type }))
    const link = document.createElement('a')
    link.href = url
    link.setAttribute('download', `${fileName}`)
    document.body.appendChild(link)
    link.click()
    window.URL.revokeObjectURL(url); // 释放内存
  }
}

export {
  dataToFile
}

vue3.x 接收后端文件流下载文件(六)

3、接口请求跨域处理
项目根目录下新建vue.config.js

const path = require("path");

module.exports = {
  devServer: {
    proxy: {
      "/api": {
        target: "http://127.0.0.1:3000",
        changeOrigin: true,
        pathRewrite: {
          "^/api": "/"
        }
      }
    }
  }
};

项目地址: https://gitee.com/smallgrey/vue3-element-ui
微信公众号:趣享编程

上一篇:MAL-PEG2k-DSPE 含有马来酰亚胺和磷脂的PEG


下一篇:java计算个人所得税,月收入的5000元以上部分征20%,800元以上5000元之间部分需缴纳3%的税,800元以下的部分免税。