vue前后端分离图片无法显示的问题

遇到的问题

在实现vue与后端实现图片上传与回显中我遇到了图片显示不出的问题(使用了虚拟路径进行配置),最后发现我是访问路径错误,同时也有文件名带中文的图片。

前端我使用的是el-upload组件来进行文件的上传

<template slot-scope="scope">
    <div class="singer-img">
        <img :src="getUrl(scope.row.pic)" style="width:100%"/>
    </div>
    <el-upload :action="uploadUrl(scope.row.id)" :before-upload="beforeAvatorUpload"
        :on-success="handleAvatorSuccess">
        <el-button size="mini">更新图片</el-button>
    </el-upload>
</template>

后端controller

@RequestMapping(value = "/updateSingerPic",method = RequestMethod.POST)
public JsonResult<String> updateSingerPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){
    if(avatorFile.isEmpty()){
        throw new FileEmptyExcepetion("文件为空");
    }
    //获取最后一个.的下标
    int index = avatorFile.getOriginalFilename().lastIndexOf(".");
    //获取文件的后缀名
    String suffix = avatorFile.getOriginalFilename().substring(index);
    //文件名=当前时间到毫秒+uuid+文件后缀名
    String fileName = System.currentTimeMillis()+ UUID.randomUUID().toString()+suffix;
    //文件路径
    String filePath = Consts.SINGERPICADDRESS;
    //如果文件路径不存在,新增该路径
    File file1 = new File(filePath);
    if(!file1.exists()){
        file1.mkdir();
    }
    //实际的文件地址
    File dest = new File(filePath+System.getProperty("file.separator")+fileName);
    //存储到数据库里的相对文件地址
    String storeAvatorPath = "/img/singerPic/"+fileName;
    System.out.println("存储到数据库的"+storeAvatorPath);
    System.out.println(dest);
    System.out.println(id);
    try {
        avatorFile.transferTo(dest);
    } catch (IOException e) {
        throw new FileUploadIOException("文件读写异常");
    }catch (FileStateException e){
        throw new FileStateException("文件状态异常");
    }
    Singer singer = new Singer();
    singer.setId(id);
    singer.setPic(storeAvatorPath);
    boolean flag = singerService.update(singer);
    if(!flag){
        throw new UpdateException("更新数据时产生异常");
    }
    return new JsonResult<>(OK,storeAvatorPath);
}

可能的问题

访问的图片名称中包含中文或空格

如果是出现这种错误,则只会部分包含中文或空格文件名的图片显示不出来

原因:url中传递的信息会经过转码后再传到后端,所以这里面的中文会被转译成其它的字符,导致失败,然后报404

解决方案1:修改图片的文件名;

解决方案2:application.properties中配置如下即可

# 解决url中中文路径的问题
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

虚拟路径配置错误,访问路径错误

真实路径最后必须要有/

将路径设置为常量放在一个工具类中:

public static final String SINGERPICADDRESS="F:"+System.getProperty("file.separator")+"Picture"+System.getProperty("file.separator")+"img"+System.getProperty("file.separator")
        +"singerPic";

虚拟路径配置如下:

System.getProperty(“file.separator”):作用相当于/

举例子:

addResourceHandler中的路径为前端访问的src路径(即创建的虚拟路径):"/img/singerPic/**",在前端url栏中输入/img/singerPic/+图片文件名即可访问到该图片

如果你的图片放在C盘下的img文件夹内,则addResourceLocations内的配置路径为(即需要映射的真实路径):"file:"+System.getProperty("file.separator")+"img"+System.getProperty("file.separator")

@Configuration
public class FileConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/img/singerPic/**").addResourceLocations(
        //歌手头像地址
        //Consts.SINGERPICADDRESS为上述设置的常量
                "file:"+Consts.SINGERPICADDRESS+System.getProperty("file.separator")
        );
    }
}

注意点:映射的真实路径最后面一定要有System.getProperty("file.separator")或者/

这个时候你访问http://localhost:8888/img/singerPic/wanglihong.jpg即可成功显示

image-20220419175237713

访问路径错误

比如我设置的虚拟路径为:/img/singerPic/**,我需要访问目录下的wanglihong.jpg文件,则我访问的路径应该是:http://localhost:8888/img/singerPic/wanglihong.jpg,注意其中的/不能多。

如果你的项目有设置项目名,则还应该在路径上添加上项目名

项目未进行热部署

如果项目没有进行热部署的话,每次更新图片后都需要手动重启服务器才能正常显示图片,具体操作网上有很多。

扩展

  1. 在文件上传中出现文件读写异常的问题

    这个错误在于创建文件目录时

    原因:不能在static文件中去自动创建目录,需要你自行创建好
    项目没有进行热部署的话,每次更新图片后都需要手动重启服务器才能正常显示图片,具体操作网上有很多。

在 Spring Boot 和 Vue 前后端分离架构中,实现文件预览可以通过前端发送请求获取文件的 URL,然后在前端使用相关插件或组件进行文件预览。 下面是一种可能的实现方式: 1. 后端实现: - 在 Spring Boot 中配置静态资源路径,将存储文件的文件夹路径设置为静态资源路径。例如,可以在 `application.properties` 文件中添加以下配置: ``` spring.resources.static-locations=file:/path/to/files/ ``` - 后端提供一个接口,用于返回文件的URL。可以在控制器中编写如下代码: ```java @RestController public class FileController { @Value("${spring.resources.static-locations}") private String staticResourcePath; @GetMapping("/api/file/{fileName}") public ResponseEntity<Resource> getFile(@PathVariable String fileName) throws IOException { Path filePath = Paths.get(staticResourcePath + fileName); Resource resource = new UrlResource(filePath.toUri()); if (resource.exists() && resource.isReadable()) { return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"") .body(resource); } else { // 文件不存在或无法读取 return ResponseEntity.notFound().build(); } } } ``` 2. 前端实现: - 在 Vue 组件中,使用 axios 或其他网络请求库发送 GET 请求,获取文件的 URL。例如: ```javascript import axios from 'axios'; // 在组件中调用接口获取文件 URL axios.get('/api/file/fileName.pdf') .then(response => { const fileUrl = response.data; // 使用文件预览插件或组件进行预览 // 例如,可以使用 pdf.js 进行 PDF 文件预览 // 或者使用 <img> 标签显示图片、使用 <video> 标签播放视频等 }) .catch(error => { console.error(error); }); ``` 需要注意的是,上述代码只是一种简单的实现方式,具体的预览方式和插件选择取决于你要预览的文件类型。你可以根据实际需求选择合适的插件或组件来实现文件预览功能,例如 pdf.js、viewer.js 等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的大雄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值