文档章节

UEditor+nodejs+seaweedfs图片服务器搭建

CoinIdea
 CoinIdea
发布于 2018/08/29 14:58
字数 1475
阅读 57
收藏 2

参考链接: 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为主的,之所以按各种动态语言再细分版本,我的理解是主要是在图片上传这一涉及到与服务器交互的功能上。 在众多版本中,没有提供nodejs的版本,下面将介绍如何用PHP版本的UEditor改造成nodejs版本的UEditor。 咨询查看PHP版本的所有请求,发现action参数值包括config(配置文件)、uploadimage(图片上传)、listimage(在线管理)、catchimage(抓取图片),所以只需要重写这4个请求就基本上实现了我们的需求。 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,根据自己的操作系统选择特定的包下载即可。本文演示的windows7 x64下载安装。傻瓜式安装好之后,需要配置一下环境变量:

GOROOT=D:\Go16
GOPATH=D:\ImageServer\seaweedfs
PATH=D:\Go16\bin

GOPATH环境变量,这个变量很重要,我自己写的代码要放到这个变量中配置的目录中,go编译器才会找到并编译

3. seaweedfs的编译运行

Github上吧seaweedfs的代码clone下来,然后安装makefile中的执行也可以直接直接makefile。在seaweedfs中执行控制台:

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

image

weed volume –dir=”./tmp/data1” –max=5 –mserver=”localhost:9333” –port=8080 &
[![image](http://upload-images.jianshu.io/upload_images/13720662-4e045e11d550fd66.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image003")](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);
});

运行效果:

image

image

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

© 著作权归作者所有

共有 人打赏支持
CoinIdea
粉丝 2
博文 37
码字总数 25824
作品 6
海淀
程序员
私信 提问
搭个专门的图片服务器,大家指教一下。

公司网站平台搭建需要有专门的服务器支持,网站图片多,而且个人有相册,内容庞大,有类似qq空间相册。需要搭建一个专门的服务器用于图片管理,想请教大家怎么搭建好。 1 采用哪种现有的技术...

熊二哈
2012/07/03
507
5
拟机搭建的ngnix和vsftpd的问题

虚拟机搭建的ngnix 和 vsftpd服务器物理机浏览器不能访问。 主机电脑通过ftp工具能访问。但是上传的图片物理机浏览器不能访问。 搭建ngnix 和vsftpd服务器 用来供主机做图片服务器使用。 使用...

Only_Joe
2016/11/26
267
8
用WordPress搭建个人网站(1)

WordPress是世界著名的个人博客系统,这阵子一直在研究它的使用方法,也买了域名,搭建起了自己的个人博客网站——http://www.initobject.com/ 域名含义即——初始化对象(init Object)。 ...

叶应是叶
2016/09/18
0
0
Java实现把图片上传到图片服务器(nginx+vsftp)

前言: 在我另一篇笔记中已经记载了如何用nginx + vsftp搭建图片服务器(请参考nginx + vsftp搭建图片服务器),并且用vsftp的客户端工具filezilla测试过已经可用。但是在开发中应该是把用户在前...

贪挽懒月
2018/05/30
0
0
新手向一键脚本搭建SS/SSR服务并开启BBR加速

自己写的一键搭建shadowsocks/shadowsocksR的脚本,一键脚本适用Vultr上的和搬瓦工所有机型(CentOS、Ubuntu、Debian),搭建ss服务器支持所有客户端类型,本机你是iOS,Android,Windows,M...

flyzy2005
2018/06/10
0
2

没有更多内容

加载失败,请刷新页面

加载更多

zeppelin源码分析(6)——note的执行过程

上图是zeppelin的前后台交互模型,zeppelin采用单独的jvm来启动interpreter进程,该Interpreter进程与zeppelinServer进程之间采用Thrift协议通信,其中RemoteInterpreterProcess是Thrift-Cl...

群星纪元
23分钟前
1
0
promise

Promise是异步里面的一种解决方案,解决了回调嵌套的问题。 语法: new Promise( function(resolve, reject) {...} /* executor */ ); executor是带有 resolve 和 reject 两个参数的函数 。...

东东笔记
25分钟前
0
0
精华集锦 | 阿里如何提升团队的研发效能?

项目管理、交付、托管、测试、运维帮您告别996,追赶“211”,海量资源0元起,尽在开发者分会场, 云效鼓励师:以下是我们整理的云效公众号上【研发效能】相关的爆款文章,这些内容中有许多都...

zhaowei121
30分钟前
2
0
收集一些有用的

1 服务器镜像下载站点: https://msdn.itellyou.cn/ 2 Windows2012 r2 产品id: NB4WH-BBBYV-3MPPC-9RCMV-46XCB 3 软件下载: https://www.filepuma.com/https://www.manageengine.cn/ 4 ......

拜了个拜
36分钟前
0
0
HIVE 常见的内置函数

文章目录 1 关系运算 1.1 1、等值比较: = 1.2 2、不等值比较: 1.3 3、小于比较: < 1.4 4、小于等于比较: <= 1.5 5、大于比较: > 1.6 6、大于等于比较: >= 1.7 7、空值判断: IS NULL 1.8 8、非...

瑞查德-Jack
45分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部