ivew组件上传图片文件的功能:
解决的问题:
1、使用view的<Upload>组件实现图片文件的上传。
2、<Upload>组件action请求地址无法到自己写的后台。
3、前台base64的图片展示。
4、文件伪造。(修改文件的后缀为图片格式的后缀)。
需求很简单:
将某一模块的编辑页面的"XX图片"字段由文本框输入改成上传图片。或者新增一个图片上传的属性。
要求:
1、 前端图片展示用BASE64格式的形式展示。
一、完成后的效果图:
1、上传前

2、点击相机,选择图片文件进行上传。
2.1 文件格式的校验

2.2 文件大小的限制

3、上传后

4、点击图片中的眼睛图标,可以对图片进行放大查看。

5、点击图片中的垃圾筒的图标,可以对图片进行删除。回到上传前。

二、前端vue组件代码。
官网地址:
https://www.iviewui.com/components/upload
<template>
<div class="demo-upload-list" v-if="formData.stationPic">
<template>
<img :src="formData.stationPic">
<div class="demo-upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView()"></Icon>
<Icon type="ios-trash-outline" @click.native="handleRemove()"></Icon>
</div>
</template>
</div>
<Upload
ref="upload"
:show-upload-list="false"
:on-success="handleSuccess"
:format="['jpg','jpeg']"
:max-size="2048"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
:headers="headers"
type="drag"
action="/api/zclanes/upload"
style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
</div>
</Upload>
<Modal title="View Image" v-model="visible">
<img :src="formData.stationPic" v-if="visible" style="width: 100%">
</Modal>
</template>
data() {
return {
headers: {'Sonep-Token': CacheUtil.getSession('access-token')},
visible: false,
},
methods: {
handleView() {
this.visible = true;
},
handleRemove() {
this.formData.stationPic = null;
},
handleSuccess(res, file) {
if (res.status === 200) {//上传成功
this.$Message.success('上传成功');
this.formData.stationPic = res.data;
} else {
this.$Message.error('上传失败');
}
},
handleFormatError(file) {
this.$Notice.warning({
title: '文件格式不正确',
desc: file.name + '的文件格式不正确, 请选择jpg或者jpeg格式的图片'
});
},
handleMaxSize(file) {
this.$Notice.warning({
title: '超出文件大小限制',
desc: file.name + '文件太大,不能超过2M.'
});
},
handleBeforeUpload() {//上传文件之前的钩子,参数为上传的文件,若返回 false 或者 Promise 则停止上传
}
},
三、后端代码
3.1 controller
/**
* 图片上传
* @param file
* @return
*/
@RequestMapping("/upload")
public ResponsePayload upload(MultipartFile file){ return service.upload(file);
}
3.2 service
@Override
public ResponsePayload upload(MultipartFile file) { try {
//判断文件是不是图片
BufferedImage image = ImageIO.read(file.getInputStream());
if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {
return ResponseUtil.getFailResponse(HttpStatus.SC_BAD_REQUEST, "你上传的不是图片文件");
}
} catch (IOException e) {
e.printStackTrace();
return ResponseUtil.getFailResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "上传异常, 请稍后再试...");
} //获取存放文件的临时路径
String filePath = IOHelper.checkPath(System.getProperty("java.io.tmpdir") + "img/");
// String filePath = FileUtils.getDataFilePath("d:/img");
//1. 获取文件的原始名称
String originalFilename = file.getOriginalFilename();//timg (1).jpg
//1.1 获取最后一个.的位置
int lastIndexOf = file.getOriginalFilename().lastIndexOf(".");
//1.2 获取文件的后缀名 .jpg
String suffix = originalFilename.substring(lastIndexOf);
//2. 重命名文件名称
String fileName = UUID.randomUUID().toString() + suffix;
File savedFile = new File(filePath, fileName);
try {
file.transferTo(savedFile);
//转BASE64
String path = savedFile.getPath();
//返回BASE64图片字符串
return ResponseUtil.success(ImageBase64Utils.toBase64(path));
} catch (IOException e) {
e.printStackTrace();
return ResponseUtil.getFailResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,"上传异常, 请稍后再试...");
} finally {
//删除本地保存的图片
savedFile.delete();
} }
四、问题回顾及解决
我们依次看下文章开头提到的4个问题
4.1 使用view的<Upload>组件实现图片文件的上传。
可以看下本文的第二部分:前端vue组件代码。
同时也给出官网地址:
https://www.iviewui.com/components/upload
4.2 <Upload>组件action请求地址无法到自己写的后台。
这个问题很恶心。
4.2.1 action地址的写法
官网用的是自己写的请求地址:action="//jsonplaceholder.typicode.com/posts/"。仔细一看是什么鬼,怎么有两个斜杠。
运行下官网的例子:
我们看到发送的请求是:https://jsonplaceholder.typicode.com/posts/。

仔细分析下:发现地址前面是带域名的:jsonplaceholder.typicode.com
这里有几种写法:
写法一:如果域名是不变的。
action="//localhost:8080/api/zclanes/upload" ---> http://localhost:8080/api/zclanes/upload
写法二:不加域名的写法。(本文用的是这种)
action="/api/zclanes/upload" ---> http://localhost:8080/api/zclanes/upload
4.2.2 请求的发送
填写完正确的地址后,后台代码也写好了。重启项目后,请求发送不出去。
我这里最后查出来是少加了个请求头。猜测:项目有auth功能,每个请求都必须加鉴权的请求头进行鉴权。如果有跟我一样的问题,找到要加的请求头,把请求头加上去就ok了。部分代码如下,详细代码上文有。其实想说明的是,<Upload>组件请求头如何添加。 其实还可以添加请求参数,具体参考官网API。
:headers="headers"
headers: {'Sonep-Token': CacheUtil.getSession('access-token')},
4.2.3 前台base64的图片展示。
参考地址:https://www.cnblogs.com/hjw-zq/p/8821898.html
其实就一句代码:
formData.stationPic: 就是后台返回的BASE64的字符串。
<img :src="formData.stationPic">
base图片展示原理: https://www.cnblogs.com/zdz8207/p/web-image-base64.html
个人理解:将图片文件转成BASE64格式的字符串。由页面自动会解析BASE64格式的图片文件。跟图片文件所在路径没有关系。也就是说,转完BASE64格式后,你把本地的图片删了都没事。
4.2.4 文件伪造。(修改文件的后缀为图片格式的后缀)。
其实解决完上面三个问题,这个功能完成的就八九不离十了。 当我在测文件大小限制的时候,我电脑里没找到2M的图片,于是我就找了个2M的excel文件,把它的后缀名改成了图片格式进行上传。测试通过。于是我就想到了,如果小于2M的文件改了会上传成功么。 答案肯定是不允许的,因为它本质就不是图片。测试也能上传成功,但就是显示不出图案来。这肯定是不对的。
于是我就想到了还少个判断文件是否是图片的逻辑。
Java判断文件是否是图片:
参考地址:https://blog.csdn.net/itjauser/article/details/97395034
五、小结:
图片上传看似简单的一个动作,其实过程很复杂。
流程大致如下:
1、选择上传的文件,发送请求。(这里请求的业务逻辑有很多种解决方案,可以把图片上传到服务器(七牛云、阿里云、本地的数据库等)。或者转成BASE64格式的字符串。不管哪种实现方式,目的都是为了把图片以某种形式存放起来,并将图片地址存放的地址返回,在前台进行显示)。
2、 将图片以BASE64的形式存储。
3、 返回BASE64字符串。
4、 拿到后台响应的图片地址,进行展示。
ImageBase64Utils 工具类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; public class ImageBase64Utils {
private static Logger log = LoggerFactory.getLogger(ImageBase64Utils.class);
public static String toBase64(String filePath) {
FileInputStream fis = null;
String base64Prefix = "data:image/jpeg;base64,";
String imgStr = "";
try {
File file = new File(filePath);
if(file.exists()) {
fis = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
int offset = 0;
int numRead = 0;
while (offset < buffer.length && (numRead = fis.read(buffer, offset, buffer.length - offset)) >= 0) {
offset += numRead;
}
if (offset != buffer.length) {
log.error("图片文件未读取完毕!");
}
fis.close();
BASE64Encoder encoder = new BASE64Encoder();
imgStr = base64Prefix + encoder.encode(buffer);
}
} catch (Exception e) { } finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
}
}
}
return imgStr;
}
}
最后,不喜勿喷。 有想法可以在下面留言,一起交流。
ivew组件上传图片文件的功能:的更多相关文章
- angularJs中上传图片/文件功能:ng-file-upload
原文技术交流:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/angularjs-ng-file-upload/ 在做网站的过程中难 ...
- .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍
Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...
- .NET跨平台之旅:增加文件日志功能遇到的挫折
在将我们的ASP.NET 5示例站点(about.cnblogs.com)升级至ASP.NET 5 RC1的时候,我们增加了控制台日志功能. 在ASP.NET 5添加日志功能很简单,只需在projec ...
- 利用其它带文件防护功能的软件防止*.asp;*.jpg写入文件。
此木马是一个.NET程序制作,如果你的服务器支持.NET那就要注意了,,进入木马有个功能叫:IIS Spy,点击以后可以看到所有站点所在的物理路径.以前有很多人提出过,但一直没有人给解决的答案.. 防 ...
- 转: KindEditor 图片空间文件增加删除文件、文件夹功能(ASP语言环境)
KindEditor 图片上传功能中集成的图片空间文件管理插件可以对已上传图片进行管理,十分便捷,只是没有图片删除功能,仔细研读xieliang分享的经验后,自己动手改造了一下,顺便分享给有同样需求的 ...
- 利用 FormData 对象和 Spring MVC 配合可以实现Ajax文件上载功能
Ajax文件上载 利用 FormData 对象和 Spring MVC 配合可以实现Ajax文件上载功能: 步骤 导入组件并准备静态脚本 <dependency> <groupId& ...
- C#使用FileSystemWatcher控件实现的文件监控功能示例
本文实例讲述了C#使用FileSystemWatcher控件实现的文件监控功能.分享给大家供大家参考,具体如下: FileSystemWatcher 可以使用FileSystemWatcher组件监视 ...
- JS 上传图片 + 预览功能(一)
JS 上传图片 + 预览功能 <body> <input type="file" id="fileimg1" style="disp ...
- jquery组件WebUploader文件上传用法详解
这篇文章主要为大家详细介绍了jquery组件WebUploader文件上传用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 WebUploader是由Baidu WebFE(FEX)团队开发的一 ...
随机推荐
- 微信小程序_简单组件使用与数据绑定
简单的数据传值 官方文档:传送门 点击"按钮"测试后,按钮文本改变,下方text文本改变,通过console.log()在输出台中打印按钮文本信息 程序结构 Page({ //页面 ...
- php的intval函数
PHP intval() 函数 PHP 可用的函数PHP 可用的函数 intval() 函数用于获取变量的整数值. intval() 函数通过使用指定的进制 . PHP , PHP , PHP 语法 ...
- Java并发编程的艺术笔记(九)——FutureTask详解
FutureTask是一种可以取消的异步的计算任务.它的计算是通过Callable实现的,多用于耗时的计算. 一.FutureTask的三种状态 二.get()和cancel()执行示意 三.使用 一 ...
- C++入门经典-例6.1-一维数组元素
1:代码如下: // 6.1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...
- 有关ajax中的URL问题
url : ../../Service/MSD_Maintain.ashx/?action=Add4T2 url : Handler/MaintainHandler.ashx/?action= ...
- webConfig的使用
<sessionState mode="Off|InProc|StateServer|SQLServer" cookieless="true|false" ...
- __doPostBack function
__doPostBack function Hi everyone. Today I am going to talk about the __doPostBack function, because ...
- linux (一)
一.文件目录 cd 目录进出 pwd 查看路径 ls:ll 查看目录 mkdir : mkdir -p app/test 创建目录 touch 创建文件 rm :rm -r 递归 -f 强制 mv ...
- prism App.config 配置
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...
- 解决 /usr/lib/x86_64-linux-gnu/liblapack.so.3: undefined reference to `gotoblas'
最近需要用到openblas库,本地ubuntu 系统内有一个版本,但是想用自己新编译的openblas, 使用cmake指定了链接的库地址, SET(LINK_LIB_DIRS "/usr ...