参考文章:
用纯css美化按钮
vue+axios实现文件上传简单原理以及操作
萌新用vue + axios + formdata 上传文件的爬坑之路
从0开始做一个的Vue图片/ 文件选择(上传)组件[基础向]
vue中利用axios实现文件上传进度实时更新
Vue实现带进度条的文件拖动上传
spring boot 文件上传
阿里巴巴iconfont怎么是正确的使用方式?
实现效果
1.用html和css画出文件上传组件
参考文章用纯css美化按钮并且利用里面的样式实现。
其中文章的要点是:
1.1文件上传使用
1.2组合label标签和美化文件上传
label好用在于,它可以跟input的click事件关联上,这就实现了语义化解决方案。因此点击这两个元素的任何一个都能得到相同的结果——弹出文件上传选择对话框。
其中隐藏标签的css为:
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
你可能会好奇为什么宽和高会设成0.1px而不是0px,因为在某些浏览器下0宽高将会让元素被tab键忽略。而position: absolute的目的是不干扰随后元素的位置。
1.3html+css实现静态页面代码
上传文件
-
{{ file.name }}
1.4实现效果
1.5icon
在静态页面中引用了阿里的icon库。引入方式可以参考:
阿里巴巴iconfont怎么是正确的使用方式?
详细的步骤为:搜索获取适合的图标->加入购物车->添加至项目->下载->将对应iconfont.css复制至css文件夹下引用即可
2.构造form'Data,使用axios上传文件
在项目中使用axios上传文件,记得new一个纯净的axios或者考虑用ajax请求。因为axios在项目估计已经用了全局配置请求头等信息,这里的配置可能被全局请求头拦截,导致请求失败。
2.1构造formData
let param = new FormData();
param.append("name", "wiiiiiinney");
//通过append向form对象添加数据
param.append("file", file);
//FormData私有类对象,访问不到,可以通过get判断值是否传进去
console.log(param.get("file"));
2.2以下为全局请求头的配置
let config = {
//添加请求头
headers: { "Content-Type": "multipart/form-data" },
//添加上传进度监听事件
onUploadProgress: e => {
var completeProgress = ((e.loaded / e.total * 100) | 0) + "%";
this.progress = completeProgress;
}
};
2.2axios发送请求
axios.post('http://127.0.0.1:8778/upload', param, config).then(
function (response)
{ console.log(response); })
.catch(function (error) {
console.log(error);
});
4.后端接收文件
java接收代码:
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 允许cookies跨域
config.addAllowedOrigin("*");// 允许向该服务器提交请求的URI,*表示全部允许。。这里尽量限制来源域,比如http://xxxx:8080 ,以降低安全风险。。
config.addAllowedHeader("*");// 允许访问的头信息,*表示全部
config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许,也可以单独设置GET、PUT等
/*
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");// 允许Get的请求方法
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
*/
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setLocation("d:/tmp");
return factory.createMultipartConfig();
}
@RequestMapping(value = "/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file,@RequestParam("name")String name) {
logger.info("name: "+name);
if (file.isEmpty()) {
return "文件为空";
}
// 获取文件名
String fileName = file.getOriginalFilename();
logger.info("上传的文件名为:" + fileName);
// 获取文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
logger.info("上传的后缀名为:" + suffixName);
// 文件上传路径
String filePath = "d:/roncoo/ttt/";
// 解决中文问题,liunx 下中文路径,图片显示问题
//fileName = UUID.randomUUID() + suffixName;
File dest = new File(filePath + fileName);
// 检测是否存在目录
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
file.transferTo(dest);
return "上传成功";
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "上传失败";
}
6.将上传信息反馈
6.1给每个文件设置一个进度条
用uploadPercentage记录上传进度,uploadPercentage的变化由axios的progress事件监听计算得出。
var item = {
name: tFiles[i].name,
uploadPercentage: 1,
size: this.formatFileSize(tFiles[i].size, 0),
uploadStatus: 0
}
console.log(item)
this.files.push(item);
6.2给每个文件设置一个上传状态
uploadStatus记录文件状态。
状态码 | 含义 |
---|---|
0 | 初始状态 |
1 | 上传中 |
2 | 已上传 |
-1 | 服务器错误 |
-2 | 上传文件类型不符合要求 |
-3 | 上传文件超出限制 |
6.3检测函数大小的函数
checkFileSize:function(fileSize) {
//2M
const MAX_SIZE = 2 * 1024 * 1024;
if (fileSize > MAX_SIZE) {
return false;
}
return true;
}
6.4检测文件类型的函数
checkFileType: function (fileType) {
const acceptTypes = ['xls', 'doc'];
for (var i = 0; i < acceptTypes.length; i++) {
if (fileType === acceptTypes[i]) {
return true;
}
}
return false;
}
6.4格式化文件大小的函数
formatFileSize: function (fileSize, idx) {
var units = ["B", "KB", "MB", "GB"];
idx = idx || 0;
if (fileSize < 1024 || idx === units.length - 1) {
return fileSize.toFixed(1) +
units[idx];
}
return this.formatFileSize(fileSize / 1024, ++idx);
},
7.全部代码
Document
上传文件
-
{{ file.name }}
{{file.size}}
出错啦,请重新上传或者删除
已上传
上传中...
出错啦,文件类型不符合要求
出错啦,文件大小超出限制