前言
前后端分离项目,或者是更一般的web项目,都有部分业务需要进行图片的展示。比如在列表中显示各种数据的图片,或是用户头像上传,甚至需要上传后回显。利用nginx是现在较为通用的解决方案。
目录
- 图片保存和显示的方式
- 配置nginx
- 前端逻辑
- 后端逻辑
1.图片保存和显示的方式
通常,前端选择本地的图片后,发送到后端。后端将图片保存到本地指定目录中,同时在数据库中存入该图片的路径。当前端需要显示时也仅仅返回拼接后的路径,这里的路径随着nginx的配置不同而不同。
2.配置nginx
通过nginx的代理,可以实现访问本地资源的需求。同时利用nginx带来的好处是,如果开发环境为windows,而部署环境为linux,只需要做不同的配置即可,代码不变。nginx.conf中的部分配置如下:
server {
listen 8086;
server_name localhost;
location /localImage {
alias D:/testImage/;
allow all;
autoindex on;
}
location / {
root html;
index index.html index.htm;
}
}
这个配置监听本地的8086端口,alias指定了一个虚拟目录,当浏览器中访问/localImage
时,就会去D:/testImage/
下找资源。比如我在D:/testImage/
下放了几张图片,在浏览器中输入http://localhost:8086/localImage/
:
点击对应图片就会进行展示,这不正是前端所需要的么,写个demo试试。
3.前端逻辑
前端使用vue,采用elementui
<template>
<div style="height: 400px; width: 400px; background-color: gray">
<el-upload
class="avatar-uploader"
:show-file-list="false"
:http-request="upload"
action="#">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</template>
对应的上传方法为:
<script>
import axios from "axios";
export default {
data() {
return {
imageUrl: ''
};
},
methods: {
upload(param){
console.log(param.file)
let formData=new FormData()
formData.append("file",param.file);
axios({
headers: {
'Content-Type': 'multipart/form-data',
},
method: 'post',
data: formData,
url: 'http://localhost:8081/upload',
}).then(res => {
this.imageUrl = res.data; //图片回显
console.log(res.data)
});
},
}
}
</script>
这里,在选择文件后,组件会将将本地图片转换为File,放在表单中进行发送。后端处理后返回该图片的url,在img标签中进行显示,实现回显功能。
4.后端逻辑
@RequestMapping("/upload")
public String upload(@RequestParam(value = "file") MultipartFile file){
String fileName = file.getOriginalFilename();
String path="D:/testImage/" + fileName;
File dest = new File( path);
try {
file.transferTo(dest); // 保存文件到本地
Image image=new Image(); //存数据库
image.setPath(path);
imageMapper.insert(image);
return "http://localhost:8086/localImage/"+fileName;
} catch (Exception e) {
e.printStackTrace();
return "false";
}
}
后端返回给前端的是一个在nginx中配置的url+图片名称,这样可以直接进行显示。效果如下:
参考