Vue前端如何配合SpringBoot后端实现文件下载

从HTML页面下载文件是非常简单的,直接向后端发起请求,后端处理请求就可以了;但是如果前端使用Vue开发,那么实现文件下载就有些曲折:Vue前端本身作为服务端存在,为了实现下载就需要将请求通过代理转到后端服务器,后端服务器将文件响应给Vue前端服务器,Vue前端服务器再实现下载,具体实现如下:

后端代码:

java 复制代码
package com.soft.backend;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;

@Controller
@RequestMapping("/api/file")
public class FileController {

    @RequestMapping("/download")
    public void download(String fileName, HttpServletResponse response) throws Exception {
        ServletOutputStream out = null;
        ByteArrayOutputStream baos = null;
        try {
            //通过输入流获取图片数据
            InputStream inStream = Files.newInputStream(new File("D:\\1.mp4").toPath());
            byte[] buffer = new byte[1024];
            baos = new ByteArrayOutputStream();
            int len;
            while ((len = inStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"),"iso-8859-1"));
            response.addHeader("Content-Length", "" + baos.size());
            response.setHeader("filename", fileName);
            response.setContentType("application/octet-stream");
            out = response.getOutputStream();
            out.write(baos.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            baos.flush();
            baos.close();
            out.flush();
            out.close();
        }
    }
}

前端代码:

vue 复制代码
<template>
	<div>
		<button type="button" @click="download">下载</button>
	</div>
</template>
<script>
	import axios from 'axios'
	export default {
		name: 'App',
		methods: {
			download() {
				var fileName="视频.mp4";
				axios(`/api/file/download`, {
					headers: {
						'Authorization': 'Bearer ' + sessionStorage.getItem('token'),
						'Content-Type': 'application/octet-stream'
					},
					methods: 'get',
					params: {
						fileName: fileName,
					},
					responseType: 'blob'
				}).then((res) => {
					if (res.status === 200) {
						const content = res.data
						const blob = new Blob([content])
						if ('download' in document.createElement('a')) { // 非IE下载
							const elink = document.createElement('a') // 创建一个a标签通过a标签的点击事件区下载文件
							elink.download = fileName
							elink.style.display = 'none'
							elink.href = URL.createObjectURL(blob) // 使用blob创建一个指向类型数组的URL
							document.body.appendChild(elink)
							elink.click()
							URL.revokeObjectURL(elink.href) // 释放URL 对象
							document.body.removeChild(elink)
						} else { // IE10+下载
							navigator.msSaveBlob(blob, fileName)
						}
					}
				}).catch(res => {
					console.log(res)
				})
			}
		}
	}
</script>
相关推荐
夜焱辰5 小时前
浏览器端 Agent 的文件版本管理:不用 Git,基于 OPFS + SQLite 自己造了一个
前端·人工智能
梦想的颜色5 小时前
TypeScript 完全指南(下):从类型体操到生产级配置
前端·javascript·typescript
Hi~晴天大圣6 小时前
npm使用介绍
前端·npm·node.js
888CC++7 小时前
如何在 C 语言中进行程序调试?
前端·javascript·算法
喵个咪7 小时前
基于 Taro 的 Headless CMS 多端前端架构:技术解析与二次开发导引
前端·react.js·taro
狂炫冰美式7 小时前
你还在古法PPT吗,试试HTML呢?免费编辑导出工具给 xdm 放这了
前端·后端·github
万少8 小时前
未来组织的分水岭不是员工数量,而是人才密度
前端·后端·面试
任磊abc8 小时前
nextjs16配置eslint+prettier
前端·eslint·nextjs·prettier
x***r1518 小时前
Another-Redis-Desktop-Manager.1.3.7安装步骤详解(附Redis可视化连接与Key管理教程)
前端·bootstrap·html
Captaincc8 小时前
你真的知道自己把 AI 用在了哪里吗?这是 Vibe Usage 想回答的问题
前端·vibecoding