參考鏈接:
http://blog.coinidea.com/web%E5%BC%80%E5%8F%91/nodejs-1161.html
1. UEditor+nodejs圖片上傳
UEditor是百度開源的富文本編輯器,功能比較強大。
下載地址是:http://ueditor.baidu.com/website/download.html
目前提供:PHP、ASP、.Net、JSP版本。UEditor主要是以前端HTML、CSS、JS為主的,之所以按各種動態(tài)語言再細分版本,我的理解是主要是在圖片上傳這一涉及到與服務器交互的功能上。
在眾多版本中,沒有提供nodejs的版本,下面將介紹如何用PHP版本的UEditor改造成nodejs版本的UEditor。
咨詢查看PHP版本的所有請求,發(fā)現(xiàn)action參數(shù)值包括config(配置文件)、uploadimage(圖片上傳)、listimage(在線管理)、catchimage(抓取圖片),所以只需要重寫這4個請求就基本上實現(xiàn)了我們的需求。
1.1 修改UEditor的ueditor.config.js的serverUrl屬性:
serverUrl: '/ue/uploads'
1.2 將ueditor/php/config.json文件名修改為config.js并移動到ueditor目錄下。
1.3 接下來主要在nodejs端編寫對應的四個action就好,圖片上傳使用了connect-busboy中間件。代碼如下:
// 圖片上傳
var path = require('path');
var uploadsPath = path.resolve('public/uploads') + '/';//存儲圖片的路徑
var busboy = require('connect-busboy');
app.use(busboy({
limits: {
fileSize: 10 * 1024 * 1024 // 10MB
}
}));
var action = {
/// 上傳圖片
uploadimage: function (req, res) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
var filesize = 0;
var ext = path.extname(filename);
var newFilename = (new Date() - 0) + ext;
fstream = fs.createWriteStream(uploadsPath + newFilename);
file.on('data', function (data) {
filesize = data.length;
});
fstream.on('close', function () {
console.log(JSON.stringify({
"originalName": filename,
"name": newFilename,
"url": '/uploads/' + newFilename,
"type": ext,
"size": filesize,
"state": "SUCCESS"
}));
res.send(JSON.stringify({
"originalName": filename,
"name": newFilename,
"url": '/uploads/' + newFilename,
"type": ext,
"size": filesize,
"state": "SUCCESS"
}));
});
file.pipe(fstream);
});
},
/// 獲取配置文件
config: function (req, res) {
return res.redirect('/js/UEditor/config.js');
},
/// 在線管理
listimage: function (req, res) {
fs.readdir(uploadsPath, function (err, files) {
var total = 0, list = [];
files.sort().splice(req.query.start, req.query.size).forEach(function (a, b) {
/^.+.\..+$/.test(a) &&
list.push({
url: '/uploads/' + a,
mtime: new Date(fs.statSync(uploadsPath + a).mtime).getTime()
});
});
total = list.length;
res.json({state: total === 0 ? 'no match file' : 'SUCCESS', list: list, total: total, start: req.query.start});
});
},
/// 抓取圖片(粘貼時將圖片保存到服務端)
catchimage: function (req, res) {
var list = [];
req.body.source.forEach(function (src, index) {
http.get(src, function (_res) {
var imagedata = '';
_res.setEncoding('binary');
_res.on('data', function (chunk) {
imagedata += chunk
});
_res.on('end', function () {
var pathname = url.parse(src).pathname;
var original = pathname.match(/[^/]+\.\w+$/g)[0];
var suffix = original.match(/[^\.]+$/)[0];
var filename = Date.now() + '.' + suffix;
var filepath = uploadsPath + 'catchimages/' + filename;
fs.writeFile(filepath, imagedata, 'binary', function (err) {
list.push({
original: original,
source: src,
state: err ? "ERROR" : "SUCCESS",
title: filename,
url: '/uploads/catchimages/' + filename
});
})
});
})
});
var f = setInterval(function () {
if (req.body.source.length === list.length) {
clearInterval(f);
res.json({state: "SUCCESS", list: list});
}
}, 50);
}
};
app.get('/ue/uploads',function (req, res) {
action[req.query.action](req, res);
});
app.post('/ue/uploads', function (req, res) {
action[req.query.action](req, res);
});
以上主要參考了博客:http://www.xiaoboy.com/detail/1341545081.html
2. GoLang的安裝與配置
1中UEditor的圖片上傳到哪兒nodejs服務器中的/public/uploads/文件夾中,如果需要高存儲、可移植、可擴展等特性的圖片服務器,則需要配置專門的服務器。本文選用的是開源的圖片(文件)分布式服務器seaweedfs。
Github地址:https://github.com/chrislusf/seaweedfs
該服務器使用GoLang編寫,所以需要安裝配置GoLang。中國的下載地址:http://www.golangtc.com/download,根據(jù)自己的操作系統(tǒng)選擇特定的包下載即可。本文演示的windows7 x64下載安裝。傻瓜式安裝好之后,需要配置一下環(huán)境變量:
GOROOT=D:\Go16
GOPATH=D:\ImageServer\seaweedfs
PATH=D:\Go16\bin
GOPATH環(huán)境變量,這個變量很重要,我自己寫的代碼要放到這個變量中配置的目錄中,go編譯器才會找到并編譯
3. seaweedfs的編譯運行
Github上吧seaweedfs的代碼clone下來,然后安裝makefile中的執(zhí)行也可以直接直接makefile。在seaweedfs中執(zhí)行控制臺:
go clean -i -v ./go/weed/
#rm –f weed #for linux
go get -v –d ./go/weed
go build -v -o weed ./go/weed
其中在get依賴的時候有可能有些依賴包不能下載,需要自己手動下載,放入:\seaweedfs\src目錄中。
推薦一個go下載包地址:https://gopm.io/download?pkgname=golang.org/x/net
Buid之后會在seaweedfs中生成一個weed,也可以將其改名為weed.exe。這個時候就可以啟動weed。以本機為演示:
weed master
weed volume –dir=”./tmp/data1” –max=5 –mserver=”localhost:9333” –port=8080 &
[](http://devhu-wordpress.stor.sinaapp.com/uploads/2016/05/image0031.png)
按照github的描述上傳、下載圖片都沒有問題。至此基本的圖片服務器搭建完成。
修改nodejs的圖片上傳代碼如下:
// 圖片上傳
var path = require('path');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
function curlPostAssign(res, filepath, filename, filesize) {
request.post(config.url_image + 'dir/assign',{},
function (error, response, body) {
if (!error && response.statusCode == 200) {
assign = eval('(' + body + ')');
var result = {};
result.res = res;
result.json = JSON.stringify({
"originalName": filename,
"name": assign.fid,
"url": '/res?fid=' + assign.fid,
"type": ext,
"size": filesize,
"state": "SUCCESS"
});
curlPostWrite(assign.fid, filepath, assign.publicUrl, result);
var ext = path.extname(filename);
}else{
console.log("Image server assign error...")
}
});
}
function curlPostWrite(fid, tmp_file, publicUrl, result) {
var files = [
{urlKey: "file1", urlValue: tmp_file}
]
var options = {
host: publicUrl.split(":")[0] ,
port: publicUrl.split(":")[1] ,
method: "POST",
path: "/" + fid
}
var req = http.request(options, function(res){
//res.setEncoding("utf8");
res.on("data", function(chunk){
//console.log("BODY:" + chunk);
})
})
req.on('error', function(e){
console.log('problem with request:' + e.message);
console.log(e);
})
postfile.postFile(files, req, result);
}
var action = {
/// 上傳圖片
uploadimage: function(req, res) {
curlPostAssign(res, req.files.upfile.path, req.files.upfile.originalFilename, req.files.upfile.size);
},
/// 獲取配置文件
config: function (req, res) {
return res.redirect('/js/UEditor/config.js');
},
/// 在線管理
listimage: function (req, res) {
fs.readdir(uploadsPath, function (err, files) {
var total = 0, list = [];
files.sort().splice(req.query.start, req.query.size).forEach(function (a, b) {
/^.+.\..+$/.test(a) &&
list.push({
url: '/uploads/' + a,
mtime: new Date(fs.statSync(uploadsPath + a).mtime).getTime()
});
});
total = list.length;
res.json({state: total === 0 ? 'no match file' : 'SUCCESS', list: list, total: total, start: req.query.start});
});
},
/// 抓取圖片(粘貼時將圖片保存到服務端)
catchimage: function (req, res) {
var list = [];
req.body.source.forEach(function (src, index) {
http.get(src, function (_res) {
var imagedata = '';
_res.setEncoding('binary');
_res.on('data', function (chunk) {
imagedata += chunk
});
_res.on('end', function () {
var pathname = url.parse(src).pathname;
var original = pathname.match(/[^/]+\.\w+$/g)[0];
var suffix = original.match(/[^\.]+$/)[0];
var filename = Date.now() + '.' + suffix;
var filepath = uploadsPath + 'catchimages/' + filename;
fs.writeFile(filepath, imagedata, 'binary', function (err) {
list.push({
original: original,
source: src,
state: err ? "ERROR" : "SUCCESS",
title: filename,
url: '/uploads/catchimages/' + filename
});
})
});
})
});
var f = setInterval(function () {
if (req.body.source.length === list.length) {
clearInterval(f);
res.json({state: "SUCCESS", list: list});
}
}, 50);
}
};
app.get('/ue/uploads',multipartMiddleware, function (req, res) {
action[req.query.action](req, res);
});
app.post('/ue/uploads',multipartMiddleware, function (req, res) {
action[req.query.action](req, res);
});

參考鏈接:
http://blog.coinidea.com/web%E5%BC%80%E5%8F%91/nodejs-1161.html

