• springboot + vue + elementui — upload解决跨域、实现图片上传


    今日记录通过elementui上传时得到的问题。

    我们在本地部署的服务,前端服务请求后端接口,存在跨域问题,

    至于为什么会有跨域这个问题?

    跨域问题确实是由Web浏览器的同源策略引起的。同源策略是浏览器的一项安全机制,它限制了从一个源加载的文档或脚本如何与来自其他源的资源进行交互。

    同源策略要求在以下三个方面完全匹配时才被认为是同源

    1. 协议(Protocol):两个页面的协议必须相同(如都是http或https)。
    2. 域名(Domain):两个页面的域名必须相同,包括子域名(如example.com和www.example.com被视为不同的域名)。
    3. 端口号(Port):两个页面的端口号必须相同(如果指定了端口号)。

    为什么后端服务跟后端服务的交互,没有跨域;而浏览器和服务器的交互有?

    因为,后端服务之间不存在同源策略的限制。

    另外,我们通常前端向后端的通信请求,一般依赖的是浏览器的通信API来完成的,当我们请求时,浏览器会检测我们请求的url是否与当前存在跨域问题。

    解决跨域:

    1.可以利用springboot解决跨域问题,这里不列举

    2.利用vue配置进行反向代理。

    vue解决跨域

    在vue.config.js文件中配置

    1. module.exports = {
    2. devServer: {
    3. proxy: {
    4. '/api': { // 请求的代称,写在Axios里的BaseUrl
    5. target: 'http://localhost:8088', // 真实请求URl
    6. ws: true,
    7. changeOrigin: true, // 允许跨域
    8. pathRewrite: { //替换,通配/api的替换成对应字符
    9. // /* 重写路径,当我们在浏览器中看到请求的地址为:http://localhost:8080/api/core/getData/userInfo 时
    10. // 实际上访问的地址是:http://localhost:8088/core/getData/userInfo,因为重写了 /api
    11. // */
    12. '^/api': '' //当你的接口中没有/api字眼时,采用这种,直接替换成空即可
    13. // '^/api': '/api' //当你的接口中刚好有/api 时,采用这种方式
    14. }
    15. }
    16. }
    17. }
    18. }

    换句话说,在本地创建了一个代理服务器,我们的请求全发到代理服务器上了 ,由代理服务器替我们发请求到后端服务器,拿到响应数据接着响应给我。

    图片上传

    java代码如下:

    1. @RestController
    2. @RequestMapping("/common")
    3. @Api(tags = "文件controller")
    4. public class CommonController {
    5. @Value("${reggie.path}")
    6. private String basePath;
    7. @ApiOperation("文件上传")
    8. @PostMapping("/upload")
    9. public Result upLoad(@RequestParam("file") MultipartFile file) {
    10. // 原始文件名 abc.jpc
    11. String originalFilename = file.getOriginalFilename();
    12. // 获取文件类型(jpg、png) .jpc
    13. String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    14. // 使用UUID重新生成文件名,防止文件名重复
    15. String fileName = UUID.randomUUID() + suffix;
    16. // 创建目录
    17. File dir = new File(basePath);
    18. if(!dir.exists()) {
    19. dir.mkdirs();
    20. }
    21. try {
    22. file.transferTo(new File(basePath + fileName)); // 当前目录下,生成图片,我们将这个路径返回
    23. } catch (IOException e) {
    24. e.printStackTrace();
    25. }
    26. return Result.success("文件上传成功", fileName);
    27. }
    28. @ApiOperation("文件下载")
    29. @GetMapping("/download")
    30. public void downLoad(String name, HttpServletResponse response) {
    31. try {
    32. // 输入流,通过输入流读取文件内容
    33. FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
    34. // 输出流,通过输出流将文件写回浏览器
    35. ServletOutputStream outputStream = response.getOutputStream();
    36. response.setContentType("image/jpeg");
    37. int len = 0;
    38. byte[] bytes = new byte[1024]; // 缓存
    39. while ((len = fileInputStream.read(bytes)) != -1) {
    40. outputStream.write(bytes, 0, len);
    41. outputStream.flush();
    42. }
    43. //关闭资源
    44. outputStream.close();
    45. fileInputStream.close();
    46. } catch (Exception e) {
    47. e.printStackTrace();
    48. }
    49. }
    50. }

     

    vue代码如下:

    1. "/api/common/upload" //后端请求上传图片接口
    2. list-type="picture-card"
    3. :show-file-list="false" // 开启上传图片列表
    4. :on-success="handleAvatarSuccess" // 成功响应后调用api,主要是这个
    5. :before-upload="beforeAvatarUpload" //上传之前调用api
    6. >
    7. <i class="el-icon-plus">i>
      <img :src="infoForm.avatar" alt="编辑头像" class="update-img">

    我们后端指定上传图片路径如上,当我们点击上传图片时,请求后端接口,图片会缓存到上述位置 ,并且会被如下函数接收到。

    1. // 获得上传图片的url
    2. handleAvatarSuccess(res, file) {
    3. console.log(file, res);
    4. this.infoForm.avatar = 'images/' + res.data
    5. // 拿到二进制数据,是blob类型,存储到浏览器内存中,一刷新数据会消失
    6. // console.log("imgUrl:", URL.createObjectURL(file.raw));
    7. },

    具体接受结果。 

    以上,我们可以2种方式,拿到图片url:

    1.  获取blob,url,但是一刷新图片会消失,因为blob url表示的图片是在浏览器内存中,而不是存储在硬盘上。
    2.  利用images/ + 图片名字.jpg

    具体就是: 我们后端缓存路径就是,vue项目中的public/images文件夹。

    为什么这样使用呢?

    浅谈一下:

    1.经过webpack打包的vue项目结构会发生改变,我们原有的图片路径会失效。

    2.public文件下,相当于是静态资源,不会经过webpack打包。

    3.vue对于静态路径和动态路径(变量)的解析不一样。

    具体看如下:

    vue图片路径问题_本郡主是喵的博客-CSDN博客

  • 相关阅读:
    PIES源码,大型体检中心源码,医院智慧体检系统源码
    基于大语言模型(LLM)的合成数据生成、策展和评估的综述
    关于Promise的用法
    odoo javascript参考(一)
    谈谈对于Java平台的理解
    超融合中国力量崛起,IDC2022年Q1报告出炉浪潮中国市场位列前三
    Centos7离线安装ALISQL5.6.32-8
    基于gitlab 15.1 pages 搭建内部博客一定行版本
    今年的数据安全风险点是什么?看数据
    一文看懂推荐系统:排序09:Field-aware Factorization Machines(FFM),从FM改进来的,效果不咋地
  • 原文地址:https://blog.csdn.net/Qhx20040819/article/details/132655779