|
|
// 引入Lodash库,它提供了很多实用的工具函数,用于处理数据、对象、数组等操作,虽然此处未明确体现具体使用的功能,但后续可能会借助它进行一些便捷的数据处理
|
|
|
var _ = require('lodash');
|
|
|
// 引入Node.js的path模块,用于处理文件路径相关的操作,比如拼接、解析路径等
|
|
|
var path = require("path");
|
|
|
// 引入Busboy模块,它常用于处理文件上传的中间件,能够方便地解析包含文件的HTTP请求中的文件数据
|
|
|
var Busboy = require('busboy');
|
|
|
// 引入Node.js的文件系统模块fs,用于对文件进行读写、查询目录等操作
|
|
|
var fs = require("fs");
|
|
|
// 引入uniqid模块,用于生成唯一的标识符,在这里可能用于为上传的文件生成唯一的文件名
|
|
|
var uniqid = require('uniqid');
|
|
|
// 引入UEditor的配置文件,通过拼接当前工作目录和配置文件的相对路径来获取其准确路径,该配置文件可能包含了UEditor相关的各种配置参数,如上传路径、允许的文件类型等
|
|
|
var ueditor_config = require(path.join(process.cwd(), "/config/ueditor.config.js"));
|
|
|
// 引入项目的上传配置信息,通过配置模块(config)获取名为"upload_config"的配置项,里面应该包含了如上传目录、基础URL等与上传相关的配置内容
|
|
|
var upload_config = require('config').get("upload_config");
|
|
|
|
|
|
// 定义允许上传的文件类型列表,以逗号分隔的字符串形式表示,目前包含了常见的图片文件类型以及ico、bmp文件类型
|
|
|
var filetype = 'jpg,png,gif,ico,bmp';
|
|
|
|
|
|
// 将一个函数作为模块的导出内容,这个函数很可能作为中间件在Express等Node.js的Web框架中使用,用于处理不同UEditor相关的请求操作,比如获取配置、上传文件、获取文件列表等
|
|
|
module.exports = function (req, res, next) {
|
|
|
// 判断请求中的查询参数action的值是否为"config",如果是,则表示客户端请求获取UEditor的配置信息
|
|
|
if (req.query.action == "config") {
|
|
|
// 使用res.jsonp方法将UEditor的配置信息(ueditor_config)返回给客户端,jsonp是一种跨域数据传输的方式,常用于解决浏览器的同源策略限制问题,使得客户端能够获取到配置数据
|
|
|
res.jsonp(ueditor_config);
|
|
|
} else if (req.query.action === 'uploadimage' || req.query.action === 'uploadfile' || req.query.action === 'uploadvideo') {
|
|
|
// 创建一个Busboy实例,用于解析包含文件上传的请求,传入请求头(headers)信息,使得Busboy能够根据请求头中的相关信息(如Content-Type等)来正确解析文件数据
|
|
|
var busboy = new Busboy({ headers: req.headers });
|
|
|
|
|
|
// 监听Busboy实例的'file'事件,当解析到文件数据时,该事件会被触发,事件回调函数接收多个参数,用于获取文件相关的各种信息
|
|
|
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
|
|
|
// 将文件名(filename)按"."进行分割,得到一个包含文件名各部分的数组,用于提取文件的扩展名
|
|
|
var fileExtArray = filename.split(".");
|
|
|
// 获取文件扩展名,即分割后的数组中的最后一个元素
|
|
|
var ext = fileExtArray[fileExtArray.length - 1];
|
|
|
// 使用uniqid模块生成一个唯一的标识符,并与文件扩展名拼接起来,作为保存文件时使用的文件名,这样可以确保文件名的唯一性,避免文件覆盖等问题
|
|
|
var save_filename = uniqid() + "." + ext;
|
|
|
// 拼接文件保存的完整路径,通过结合当前工作目录、配置中的上传目录(upload_config.get("upload_ueditor"))以及生成的文件名(save_filename)来确定最终保存位置
|
|
|
var savePath = path.join(process.cwd(), upload_config.get("upload_ueditor"), save_filename);
|
|
|
|
|
|
// 监听文件流(file)的'end'事件,当文件数据全部读取完毕后,该事件会被触发,在这里可以进行一些后续操作,比如组装返回给客户端的文件上传结果信息
|
|
|
file.on('end', function () {
|
|
|
// 组装文件上传成功后的结果对象,包含文件的访问URL、标题(可根据请求体中的pictitle字段获取,如果不存在则使用原始文件名)、原始文件名以及表示上传状态为成功的标志
|
|
|
var result = {
|
|
|
'url': upload_config.get("baseURL") + "/" + upload_config.get("upload_ueditor") + "/" + save_filename,
|
|
|
'title': req.body && req.body.pictitle || filename,
|
|
|
'original': filename,
|
|
|
'state': 'SUCCESS'
|
|
|
};
|
|
|
// 判断请求中是否包含encode参数,如果有,则使用res.jsonp方法将结果对象以JSONP的形式返回给客户端,同样是考虑到跨域等情况的一种数据返回方式
|
|
|
if (req.query.encode) {
|
|
|
res.jsonp(result);
|
|
|
} else {
|
|
|
// 如果没有encode参数,使用res.redirect方法进行重定向,重定向的URL由配置中的简单上传重定向地址(upload_config.get("simple_upload_redirect"))和文件上传结果信息(经过JSON.stringify转换为字符串形式)拼接而成,这样客户端可以根据重定向后的地址获取到上传结果信息
|
|
|
// 另一个被注释掉的res.redirect(result.url),原本可能是直接重定向到文件的访问URL,但这里采用了传递结果信息的重定向方式
|
|
|
res.redirect(upload_config.get("simple_upload_redirect") + "?result=" + JSON.stringify(result));
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 将文件流(file)通过管道(pipe)写入到创建的可写文件流(fs.createWriteStream(savePath))中,实现将上传的文件保存到指定的文件路径下
|
|
|
file.pipe(fs.createWriteStream(savePath));
|
|
|
});
|
|
|
|
|
|
// 将请求对象(req)通过管道(pipe)传入到Busboy实例中,触发Busboy开始解析请求中的文件数据,从而进入上述的文件上传处理流程
|
|
|
req.pipe(busboy);
|
|
|
} else if (req.query.action === 'listimage') {
|
|
|
// 使用文件系统模块(fs)的readdir方法读取指定目录下的所有文件,目录路径通过结合当前工作目录和配置中的上传目录(upload_config.get("upload_ueditor"))来确定,读取完成后会调用回调函数处理结果(err表示读取过程中是否出现错误,files表示读取到的文件列表)
|
|
|
fs.readdir(path.join(process.cwd(), upload_config.get("upload_ueditor")), function (err, files) {
|
|
|
// 如果读取过程中出现错误,直接结束响应,不返回任何数据给客户端(这里可以考虑返回更合适的错误信息给客户端)
|
|
|
if (err) return res.end();
|
|
|
// 初始化一个变量用于统计符合条件的文件总数,初始值为0
|
|
|
var total = 0;
|
|
|
// 创建一个空数组,用于存放符合条件的文件信息,后续会将满足文件类型要求的文件相关信息添加到这个数组中
|
|
|
var filelist = [];
|
|
|
|
|
|
// 使用Lodash的forEach方法遍历读取到的所有文件,对每个文件进行相关处理
|
|
|
_(files).forEach(function (file) {
|
|
|
// 将文件名按"."进行分割,获取文件扩展名,用于后续判断文件类型是否符合要求
|
|
|
var fileExtArray = file.split(".");
|
|
|
var ext = fileExtArray[fileExtArray.length - 1];
|
|
|
// 判断文件扩展名是否在允许的文件类型列表(filetype)中(将扩展名转换为小写后进行判断),如果是,则表示该文件符合要求,进行相应的信息组装和添加到文件列表操作
|
|
|
if (filetype.indexOf(ext.toLowerCase()) >= 0) {
|
|
|
var result_file = {};
|
|
|
// 组装文件的访问URL,格式与前面文件上传成功后的URL格式类似,通过配置中的基础URL、上传目录以及文件名来确定
|
|
|
result_file.url = upload_config.get("baseURL") + "/" + upload_config.get("upload_ueditor") + "/" + file;
|
|
|
// 将组装好的文件信息对象添加到文件列表数组中
|
|
|
filelist.push(result_file);
|
|
|
// 符合条件的文件总数加1
|
|
|
total++;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 使用res.jsonp方法将包含文件列表信息、状态(SUCCESS表示成功获取列表)、起始索引(这里固定为1)以及文件总数的结果对象返回给客户端,同样采用JSONP的方式考虑跨域等情况进行数据传输
|
|
|
res.jsonp({
|
|
|
"state": "SUCCESS",
|
|
|
"list": filelist,
|
|
|
"start": 1,
|
|
|
"total": total
|
|
|
});
|
|
|
})
|
|
|
}
|
|
|
} |