需求背景
公司项目运作起来,你会发现开发过程中图片不应该放在项目中,这样管理起来非常不方便。设计师,产品,运营都要上传产品运营图片,你们项目的样式代码也要使用图片。那么怎么做比较好?
答案当然是搭建一个与业务隔离的图片服务
那么如何快速搭建?
写个node服务(eggjs框架)
- 前端写js 将图片通过ajax传到后端接口。
- 后端接口将图片保存到磁盘的指定位置如:/mnt/data/img
- 启动node服务
- 配置nginx
Demo效果
1. 前端上传交互代码
HTML:点击上传与拖拽上传功能实现,部分代码省略,源文件可以联系博主
<html>
<head>
<title>图片上传服务</title>
<script src="/third-part/jquery/jquery-1.9.1.min.js"></script>
<style>
.box {
width: 600px;
height: 300px;
}
#pasteImg{
border: dashed;
background-image: url(/img/bg.png);
background-size: 100%;
}
#pasteImg img{
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<h2>上传图片服务</h2>
<div id="pasteImg" class="box" contenteditable="true"></div>
<form id="uploadForm">
<input type="file" name="image" style="" id="imgfile" accept="image/*">选择图片</input>
<button style="" id="btnGO">上传图片</button>
</form>
<h2>markdown/html语法</h2>
<div class="result">
<textarea class="box">
</textarea>
</div>
</body>
<script>
window.onload = function () {
function paste_img(e) {
if (e.clipboardData && e.clipboardData.items) {
var imageContent = e.clipboardData.getData('image/png');
ele = e.clipboardData.items
for (var i = 0; i < ele.length; ++i) {
//粘贴图片
if (ele[i].kind == 'file' && ele[i].type.indexOf('image/') !== -1) {
var blob = ele[i].getAsFile();
window.URL = window.URL || window.webkitURL;
var blobUrl = window.URL.createObjectURL(blob);
// 显示到div中,此时是显示的本地图片数据,并没有上传到服务器
var new_img = document.createElement('img');
new_img.setAttribute('src', blobUrl);
new_img.setAttribute('blobdata', blob);
// 移动div光标到新元素后面
insertHtmlAtCaret(new_img);
// 直接上传,当然你也可以不在这上传,可以点击按钮在上传
uploadImg(blob);
}
//粘贴文本
else if (ele[i].kind === "string" && ele[i].type.indexOf('text/plain') != -1) {
//粘贴文本回调函数
ele[i].getAsString(
function (str) {
insertHtmlAtCaret(document.createTextNode(str)); //插入文本到光标处 并移动光标到新位置
})
} else return;
}
} else {
alert('不支持的浏览器');
}
}
//绑定粘贴事件
document.getElementById('pasteImg').onpaste = function () {
paste_img(event);
return false;
};
//**blob to dataURL**
function blobToDataURL(blob, callback) {
var a = new FileReader();
a.onload = function (e) {
callback(e.target.result);
}
a.readAsDataURL(blob);
}
}
</script>
</html>
2. 后端接口将图片保存到磁盘
async upload() {
const stream = await this.ctx.getFileStream();
// const filename = encodeURIComponent(stream.fields.name) + path.extname(stream.filename).toLowerCase();;
const filename = uuid.v4() + path.extname(stream.filename).toLowerCase();
const target = path.join(this.config.imgServer.savePath, filename);
const writeStream = fs.createWriteStream(target);
try {
await awaitWriteStream(stream.pipe(writeStream));
} catch (err) {
this.ctx.logger.error('上传出错',err);
this.ctx.body = {
code: '500',
imgURL: null
};
return;
}
this.ctx.body = {
code: '0',
imgURL: this.config.imgServer.host + filename,
};
}3. 启动node服务
"start:prod": "egg-scripts start --daemon --env=prod --port=9001 --title=egg-server-image-server",4. Nginx配置
主要是配置充许上传图片的大小,如果有域名,则设置指向 9001端口的node服务。
需要源码学习请关注公众号“群鱼湾”,回复“图片服务源码”,免费取得。
