springboot + vue + elementui — upload solves cross-domain and realizes image upload

Today, I recorded the problems I got when uploading through elementui.

The service we deploy locally, the front-end service requests the back-end interface, there is a cross-domain problem,

1. You can use springboot to solve cross-domain problems, which are not listed here

2. Use vue configuration for reverse proxy.

Vue solves cross domain

Configure in the vue.config.js file

const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  transpileDependencies: true,
  // 跨域请求
  devServer: {

    port: 8080,
    // 开启代理
    proxy: {
      '/api': {
        // 后端地址
        target: 'http://localhost:8081/',
        // 允许跨域
        changeOrigin: true,
        // 路径重写:我们可以应/api,替代上述后端url
        pathRewrite: {
          '^/api': '/'
        }
      }
    }
  }

})

upload picture

The java code is as follows:

@RestController
@RequestMapping("/common")
@Api(tags = "文件controller")
public class CommonController {

    @Value("${reggie.path}")
    private String basePath;

    @ApiOperation("文件上传")
    @PostMapping("/upload")
    public Result upLoad(@RequestParam("file") MultipartFile file) {

        // 原始文件名   abc.jpc
        String originalFilename = file.getOriginalFilename();
        // 获取文件类型(jpg、png)  .jpc
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 使用UUID重新生成文件名,防止文件名重复
        String fileName = UUID.randomUUID() + suffix;

        // 创建目录
        File dir = new File(basePath);
        if(!dir.exists()) {
            dir.mkdirs();
        }

        try {

            file.transferTo(new File(basePath + fileName)); // 当前目录下,生成图片,我们将这个路径返回
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.success("文件上传成功", fileName);
    }

    @ApiOperation("文件下载")
    @GetMapping("/download")
    public void downLoad(String name, HttpServletResponse response) {
        try {
            // 输入流,通过输入流读取文件内容
            FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));

            // 输出流,通过输出流将文件写回浏览器
            ServletOutputStream outputStream = response.getOutputStream();

            response.setContentType("image/jpeg");

            int len = 0;
            byte[] bytes = new byte[1024]; // 缓存
            while ((len = fileInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
                outputStream.flush();
            }

            //关闭资源
            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

 

The vue code is as follows:

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

Our backend specifies the upload image path as above. When we click to upload an image and request the backend interface, the image will be cached in the above location and will be received by the following function.


        // 获得上传图片的url
        handleAvatarSuccess(res, file) {
            console.log(file, res);
            this.infoForm.avatar = 'images/' + res.data

            // 拿到二进制数据,是blob类型,存储到浏览器内存中,一刷新数据会消失
            // console.log("imgUrl:", URL.createObjectURL(file.raw));
        },

Specifically accept the result. 

Above, we can get the image url in two ways:

  1.  Get the blob and url, but the picture will disappear when you refresh, because the picture represented by the blob url is in the browser memory, not stored on the hard disk.
  2.  Use images/ + image name.jpg

Specifically: Our backend cache path is the public/images folder in the vue project.

Why use it like this?

Talk about:

1. The Vue project structure packaged by webpack will change, and our original image path will become invalid.

2. Under the public file, it is equivalent to a static resource, which will not be packaged by webpack.

3. Vue's analysis of static paths and dynamic paths (variables) is different.

The details are as follows:

Vue image path problem

Guess you like

Origin blog.csdn.net/Qhx20040819/article/details/132655779