最近帮学长做一个需求,总结一下在实现过程中遇到的问题,以及一些新知识的学习。
- 点击上传文件,并展示。
- 点击按钮进行测试,执行Python文件,并将指定生成文件夹中的图片展示在页面上
1. 文件的上传预览
方法一:FileReader
参考文档:MDN FileReader
<body>
<!-- multiple 属性规定输入字段可选择多个值。如果使用该属性,则字段可接受多个值。 -->
<!-- webkitdirectory 属性可以以文件夹形式上传文件 -->
<input type="file" id="selectFiles" onchange="dealSelectFiles()" multiple webkitdirectory>
<div id="showImg"></div>
<script type="text/javascript">
function dealSelectFiles() {
let selectFiles = document.getElementById("selectFiles").files; //获得一个对象,是上传的文件信息(可以是多个)
for (let file of selectFiles) {
// console.log(file.webkitRelativePath);//包含文件路径,相对于用户所选的祖先目录。调用webkitRelativePath返回的结果都不会是你希望得到的路径
let reader = new FileReader(); //返回一个新构造的FileReader。
reader.readAsDataURL(file); // 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容。
reader.onloadend = function() { // 在读取结束的时候触发
let img = new Image();
img.src = this.result; //读取完成后result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容。
img.onload = function() { // 在图片加载完成后立即执行
let showImg = document.getElementById("showImg");
showImg.appendChild(img)
}
}
}
}
</script>
</body>
方法二:URL.createObjectURL()
参考文档:MDN URL.createObjectURL()
<script type="text/javascript">
function dealSelectFiles() {
let selectFiles = document.getElementById("selectFiles").files; //获得一个对象,是上传的文件信息(可以是多个)
for (let file of selectFiles) {
let img = new Image();
let url = window.URL.createObjectURL(file); //获取到获取图片的地址,但是是经过浏览器处理不是真实的地址
img.src = url;
img.onload = function() { // 在图片加载完成后立即执行
let showImg = document.getElementById("showImg");
showImg.appendChild(img);
window.URL.revokeObjectURL(file);
}
}
}
</script>
2. 将上传的文件传给后台处理(我这里使用node.js+express框架)
A. 实现将上传的图片放到固定的文件夹中存储
实现这个功能我们需要使用:
1. fs模块
npm install --save fs
2. multer模块
multer:自己的总结https://blog.csdn.net/weixin_45773503/article/details/116461916
npm install --save multer
- Multer 会添加一个
body
对象 以及file
或files
对象 到 express 的 request 对象中。 - body 对象包含表单的文本域信息
- file 或 files 对象包含 对象表单上传的文件信息。
以下代码实现了将上传的图片放到固定的文件夹中存储
let express = require('express')
let { join } = require('path')
let multer = require('multer')
let fs = require('fs');
let app = express();
app.use(express.static(join(__dirname, 'public')))
// 1. 打开或创建一个名字叫folder文件夹
let createFolder = function(folder) {
try {
fs.accessSync(folder); // 打开文件夹
} catch (e) {
fs.mkdirSync(folder); // 创建文件夹
}
};
let uploadFolder = './upload/'; // 设定存储文件夹为当前目录下的 /upload 文件夹
createFolder(uploadFolder);
// 2. 设置磁盘存贮
let storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, uploadFolder); // 他会放在当前目录下的 /upload 文件夹下(没有该文件夹,就新建一个)
},
filename: function(req, file, cb) { // 在这里设定文件名
cb(null, file.originalname); // file.originalname是将文件名设置为上传时的文件名,file中携带的
// cb(null, Date.now() + '-' + file.originalname) // 加上Date.now()可以避免命名重复
}
})
let upload = multer({ storage: storage });
app.post('/upload', upload.single('upload'), function(req, res, next) {
res.send("success");
next();
});
B. 在发送请求后执行Python文件
方法一: 使用了jsexecpy模块执行Python文件
app.get('/test', (req, res) => {
let jsexecpy = require("jsexecpy");
jsexecpy.runpath("./public/python/star.py");
})
但是需要传递参数,并且还要执行cmd命令,所以又有了
方法二: 使用child_process(执行cmd命令)
app.get('/test', (req, res) => {
let cmd = 'python D:/DeskTop/star.py --source';
// Sync同步执行
process.execSync(cmd, function(error, stdout, stderr) {
console.log("error:" + error);
console.log("stdout:" + stdout);
console.log("stderr:" + stderr);
});
})
C: 获取某一个文件夹下的所有的图片
需要用到的模块
let fs = require('fs'); //引用文件系统模块
let image = require("imageinfo"); //引用imageinfo模块
const { join } = require('path');
递归获取文件夹下的文件(封装成函数,并开放出去)
// 定义遍历目录的方法
function readFileList(path, filesList) {
var files = fs.readdirSync(path);
files.forEach(function(item, index) {
// 获取文件信息
var stat = fs.statSync(path + item); //用于递归
// 是否为目录(isDirectory)
if (stat.isDirectory()) { //递归读取文件
readFileList(path + item + "/", filesList)
} else {
var obj = {}; //定义一个对象存放文件的路径和名字
obj.path = path; //路径
obj.filename = item //名字
filesList.push(obj);
}
})
}
module.exports = getFiles = {
//获取文件夹下的所有文件
getFileList: function(path) {
var filesList = [];
readFileList(path, filesList);
return filesList;
},
//获取文件夹下的所有图片的路径
getImageFiles: function(path) {
var imageList = [];
this.getFileList(path).forEach((item) => {
var ms = image(fs.readFileSync(item.path + item.filename));
// console.log(ms);
ms.mimeType && (imageList.push(join(item.path, item.filename)))//拼接上public路径
});
return imageList;
}
};
// 获取文件夹下的所有图片的
// console.log(getFiles.getImageFiles("./public/images/"));
以上能够获取public文件夹下图片的名称,并且拼接上了public路径,通过public将其开放出去并在页面上展示了。
总结:在这次的的案例实现过程中,看似很简单的操作,实际敲起代码来却并不顺利,对于node基础知识掌握的还不是很牢固,还需要不断的复习与使用。这两天也学到许多新知识,希望在技术的路上越走越深。