Springboot + vue + axios + fdfs 实现(图片)文件下载

前后端分离下载Fdfs文件代码及一些坑

坑一:跨域问题引起导致的前端res对象拿不到response的header
前后端分离架构中,跨域问题是个老大难,但springboot其实解决了很多问题,比
如加注解@CrossOrigin该controller就可以被跨域请求,然而像我这种懒人搞文
件上传的时候依旧只加一个注解问题就来了,前端res对象死活没有我设置的
header,恰巧content-type却是有的,然后我就百度了一个上午 为什么设置了
header不生效拿不到数据等等等,有些说什么设置的先后顺序(难道老夫连顺序都
不知道吗)。后来我悄然在抓包中发现header居然都有,我擦嘞

Springboot + vue + axios + fdfs 实现(图片)文件下载_第1张图片

但就是axios响应回来的res对象没有我自己设置的header

Springboot + vue + axios + fdfs 实现(图片)文件下载_第2张图片

于是果断想到,可能是跨域引起的拦截,果然需要配置放行
response.setHeader("Access-Control-Expose-Headers", "filename");
这表示要放行filename参数,配了过后才像上面那张图一样有了filename
 
坑二:响应数据乱码问题
在响应回来的数据中全是乱码,下载后图片也打不开,但是preview是能够预览图片
的就像这样

Springboot + vue + axios + fdfs 实现(图片)文件下载_第3张图片

这个的问题就在于前端了,我这个所谓的后端菜鸡程序员可不是很会鸭,不过还是被我找到了解决办法。

由于axios使用封装过后的请求设置请求头responseType:'blob’不生效,所以要使用axios({})的方式,不要使用如:axios.get()的方式(我这么懒自然从来都是axios.get()啦)。改了之后果然就好了

Springboot + vue + axios + fdfs 实现(图片)文件下载_第4张图片

图片自然也正常了。

最后呢贴代码

    @GetMapping("/download/{photoId}")
    @CrossOrigin
    public void downLoad(@PathVariable String photoId, HttpServletResponse response) throws IOException {
     Photo photo =  photoService.findById(photoId);
        if (photo != null){
          byte[] file = fastFileStorageClient.downloadFile("group1",photo.getFullUrl().substring(photo.getFullUrl().indexOf("/") +1) , new DownloadByteArray());
            response.reset();
                response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(photo.getName(),"UTF-8"));
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Expose-Headers", "filename");
            response.setContentType("octet-stream");// image/jpeg
            response.setHeader("filename",photo.getName());
            ServletOutputStream outputStream = response.getOutputStream();
            IOUtils.write(file,outputStream);
            outputStream.close();
            }

前端代码:

methods:{
        handleDownload(row){
          this.$http({
            method: 'GET',
            url: 'http://localhost:8989/file/download/' + row.id,

            responseType: 'blob'
          }).then(res=>{
            const blob = new Blob([res.data])
            let url = window.URL.createObjectURL(blob)

            //创建一个a标签元素,设置下载属性,点击下载,最后移除该元素
            let link = document.createElement('a')
            link.href = url
            link.style.display = 'none'
            //res.headers.fileName 取出后台返回下载的文件名
            const downlaodFileName = decodeURIComponent(res.headers.filename)
            console.log(res)
            link.setAttribute('download',downlaodFileName)
            link.click()
            window.URL.revokeObjectURL(url)
          }).catch((res)=>{
            console.log(res)
            this.$message.error("下载失败")
          })
//以下是之前会乱码的代码
          //
          // this.$http.get("http://localhost:8989/file/download/"+ row.id,{
          //   headers :{
          //     responseType: 'blob'
          //   }
          // }).then(res=>{
          //   const blob = new Blob([res.data],{type: "image/jpeg"})
          //   let url = window.URL.createObjectURL(blob)
          //
          //   //创建一个a标签元素,设置下载属性,点击下载,最后移除该元素
          //   let link = document.createElement('a')
          //   link.href = url
          //   link.style.display = 'none'
          //   //res.headers.fileName 取出后台返回下载的文件名
          //   const downlaodFileName = decodeURIComponent(res.headers.filename)
          //   console.log(res)
          //   link.setAttribute('download',downlaodFileName)
          //   link.click()
          //   window.URL.revokeObjectURL(url)
          // }).catch((res)=>{
          //   console.log(res)
          //   this.$message.error("下载失败")
          // })
        }

           link.href = url
            link.style.display = 'none'
            //res.headers.fileName 取出后台返回下载的文件名
            const downlaodFileName = decodeURIComponent(res.headers.filename)
            console.log(res)
            link.setAttribute('download',downlaodFileName)
            link.click()
            window.URL.revokeObjectURL(url)
          }).catch((res)=>{
            console.log(res)
            this.$message.error("下载失败")
          })
//以下是之前会乱码的代码
          //
          // this.$http.get("http://localhost:8989/file/download/"+ row.id,{
          //   headers :{
          //     responseType: 'blob'
          //   }
          // }).then(res=>{
          //   const blob = new Blob([res.data],{type: "image/jpeg"})
          //   let url = window.URL.createObjectURL(blob)
          //
          //   //创建一个a标签元素,设置下载属性,点击下载,最后移除该元素
          //   let link = document.createElement('a')
          //   link.href = url
          //   link.style.display = 'none'
          //   //res.headers.fileName 取出后台返回下载的文件名
          //   const downlaodFileName = decodeURIComponent(res.headers.filename)
          //   console.log(res)
          //   link.setAttribute('download',downlaodFileName)
          //   link.click()
          //   window.URL.revokeObjectURL(url)
          // }).catch((res)=>{
          //   console.log(res)
          //   this.$message.error("下载失败")
          // })
        }

你可能感兴趣的:(Java笔记)