SpringBoot+vue 文件传输+跨域

SpringBoot+vue 文件传输+跨域

1:前端传输文件保存到后端:

1:导包

   <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.16</version> <!-- 使用时请检查最新版本 -->
        </dependency>

2:contoller

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile
import org.whh.base.util.AjaxResult;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

@RestController
@RequestMapping("/files")
public class FileController {

    // 文件上传存储路径
    private static final String filePath = System.getProperty("user.dir") + "/file/";

    /**
     * 文件上传
     */
    @PostMapping("/upload")
    public AjaxResult upload(MultipartFile file) {
        synchronized (FileController.class) {
            String flag = System.currentTimeMillis() + "";
            String fileName = file.getOriginalFilename();
            try {
                if (!FileUtil.isDirectory(filePath)) {
                    FileUtil.mkdir(filePath);
                }
                // 文件存储形式:时间戳-文件名
                FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName);
                System.out.println(fileName + "--上传成功");
                Thread.sleep(1L);
            } catch (Exception e) {
                System.err.println(fileName + "--文件上传失败");
            }
            return AjaxResult.success(flag);
        }
    }


    /**
     * 获取文件
     */
    @GetMapping("/{flag}")
    public void avatarPath(@PathVariable String flag, HttpServletResponse response) {
        if (!FileUtil.isDirectory(filePath)) {
            FileUtil.mkdir(filePath);
        }
        OutputStream os;
        List<String> fileNames = FileUtil.listFileNames(filePath);
        String avatar = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");
        try {
            if (StrUtil.isNotEmpty(avatar)) {
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(avatar, "UTF-8"));
                response.setContentType("application/octet-stream");
                byte[] bytes = FileUtil.readBytes(filePath + avatar);
                os = response.getOutputStream();
                os.write(bytes);
                os.flush();
                os.close();
            }
        } catch (Exception e) {
            System.out.println("文件下载失败");
        }
    }

}

3: 前端

<el-form-item label="文件上传" label-width="20%">
  <el-upload action="http://localhost:8080/api/files/upload" :on-success="successUpload">
    <el-button size="small" type="primary">点击上传</el-button>
  </el-upload>
</el-form-item>



<el-table-column label="文件下载">
  <template v-slot="scope">
    <el-image
        style="width: 70px; height: 70px; border-radius: 50%"
        :src="'http://localhost:8080/api/files/' + scope.row.img"
        :preview-src-list="['http://localhost:8080/api/files/' + scope.row.img]">
    </el-image>
  </template>
</el-table-column>
<el-button type="primary" @click="down(scope.row.img)">下载</el-button>



方法
successUpload(res) {
  上传成功后做一些操作
},

2:前端传输excel文件:

1:导包

   <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.3</version>
        </dependency>

2:controller

    @PostMapping("/easyexcel")
    public void easyexcel(@RequestBody Query query,HttpServletResponse response) throws IOException {
        this.setExcelResponseProp(response, "员工表");
        // 获取需要导出的列表
        List<EmployeeVo> easyexcelist = employeeService.get(query);

        // 设置格式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
        EasyExcel.write(response.getOutputStream())
                .head(EmployeeVo.class)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("员工表")
                .registerWriteHandler(horizontalCellStyleStrategy) //引入格式
                .doWrite(easyexcelist);
    }

    private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }


    @RequestMapping("/importScore")
    public void importScore(@RequestParam MultipartFile file,HttpServletResponse response) throws IOException {
        //读取列表
        List<EmployeeVo> importList = EasyExcel.read(file.getInputStream())
                .head(EmployeeVo.class)
                .sheet()
                .doReadSync();
        System.out.println("====================================");
        importList.forEach(System.out::println);
        // 正则表达式,用于匹配电子邮件地址
        String emailRegex = "[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+";
        Pattern pattern = Pattern.compile(emailRegex);
        List<EmployeeVo> validEmails = new ArrayList<>();
        List<EmployeeVo> invalidEmails = new ArrayList<>();
        for (EmployeeVo employee : importList) {
            String email = employee.getEmail();
            if (Objects.nonNull(email) && pattern.matcher(email).matches()) {
                validEmails.add(employee); // 如果是有效的电子邮件,添加到validEmails列表中
            } else {
                invalidEmails.add(employee); // 如果不是有效的电子邮件,添加到invalidEmails列表中
            }
        }

        // 设置格式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
        EasyExcel.write(response.getOutputStream())
                .head(EmployeeVo.class)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("错误数据表")
                .registerWriteHandler(horizontalCellStyleStrategy) //引入格式
                .doWrite(invalidEmails);
        employeeService.upInsert(validEmails);
//        if (!invalidEmails.isEmpty()){
//            return AjaxResult.success(invalidEmails);
//        }
//        return AjaxResult.success("全部成功");
    }

3:前端

<el-upload :http-request="upLoadError" action="ip/employee/importScore" >
            <el-button  type="primary">点击上传</el-button>
</el-upload>


upLoadError(data){
      let param = new FormData;
      param.append("file",data.file);
      this.$http({
        url: '/employee/importScore',
        method: 'post',
        responseType: 'blob',
        // 可根据下拉框 选择要导出信息
        data: param
      }).then(({data}) => {
        if (!data || data.size === 0) {
          this.$message({message: '列表为空', type: 'error', duration: 1500});
          return
        }
        let blob = new Blob([data], {type: 'application/vnd.ms-excel'})
        let url = window.URL.createObjectURL(blob)
        const link = document.createElement('a') // 创建a标签
        link.href = url
        link.download = '错误数据表.xls' // 重命名文件
        link.click()
        URL.revokeObjectURL(url) // 释放内存
        this.queryData();
      })

    },
    outExcel(){
      this.$http({
        url: '/employee/easyexcel',
        method: 'post',
        responseType: 'blob',
        // 可根据下拉框 选择要导出的年级或者学校名字的同学信息
        data: this.search
      }).then(({data}) => {
        if (!data || data.size === 0) {
          this.$message({
            message: '列表为空',
            type: 'error',
            duration: 1500
          })
          return
        }
        let blob = new Blob([data], {type: 'application/vnd.ms-excel'})
        let url = window.URL.createObjectURL(blob)
        const link = document.createElement('a') // 创建a标签
        link.href = url
        link.download = '员工表.xls' // 重命名文件
        link.click()
        URL.revokeObjectURL(url) // 释放内存
      })

    },

跨域

vue代理

修改 index.js ,增加如下内容:

proxyTable: {
    '/api': {	//所有以api开头的url都代理给下面的地址
        target: 'http://localhost:80',	//所有以api开头的请求,都代理给 http://localhost:80
        changeOrigin: true,
        pathRewrite: {	//路径重新
            '^/api': '' // 当请求的地址中有api开头,会去掉api吧请求定向到  http://localhost:80 后台地址
        }
    },
}

在main.js添加统一的 api前缀

axios.defaults.baseURL='/api'

页面请求效果

this.$http.post("/dept/page",para)...省略...

后端CrosFilter解决

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //1) 允许的域,不要写*,否则cookie就无法使用了
       	config.addAllowedOrigin("http://127.0.0.1:8081");
        config.addAllowedOrigin("http://localhost:8081");
        config.addAllowedOrigin("http://127.0.0.1:80");
        config.addAllowedOrigin("http://localhost:80");
        config.addAllowedOrigin("http://127.0.0.1");
        config.addAllowedOrigin("http://localhost");


        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");
        //2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new
                UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

Njinx代理

解决跨域(将前端的8088端口请求转接到后端8080端口)

server {
      listen 8088;
      server_name  localhost;
	  location / {   
		add_header 'Access-Control-Allow-Origin' $http_origin;
		add_header 'Access-Control-Allow-Credentials' 'true';
		add_header 'Access-Control-Allow-Methods' 'PATCH,GET,POST,DELETE,PUT,OPTIONS';
		add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,token,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
		add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
		if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $http_origin;
			add_header 'Access-Control-Allow-Credentials' 'true';
			add_header 'Access-Control-Allow-Methods' 'PATCH,GET,POST,DELETE,PUT,OPTIONS';
			add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,token,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
			add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

			add_header 'Access-Control-Max-Age' 1728000;
			add_header 'Content-Type' 'text/plain; charset=utf-8';
			add_header 'Content-Length' 0;
			return 204;
		}
		
		proxy_pass http://localhost:8080;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_connect_timeout 5;
	  }
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值