- form.parse()
form.parse() 是 formidable 的核心方法,用于解析传入的 multipart/form-data 请求(通常是文件上传请求)。它会自动处理文件的接收、保存等操作,并触发相关的事件。
作用:解析请求体,处理文件和字段数据。
位置:这是文件上传的主要入口点。
const formidable = require('formidable');
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
return res.status(500).send('文件上传失败');
}
console.log('接收到的文件:', files);
res.send('文件上传成功');
});
});
- form.on(‘fileBegin’)
fileBegin 事件在文件开始上传时触发。你可以在这个事件中设置文件的保存路径、文件名等。
作用:在文件开始上传时进行预处理,例如修改文件名或保存路径。
位置:在文件上传之前。
const formidable = require('formidable');
const path = require('path');
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
form.on('fileBegin', (name, file) => {
// 修改文件名和保存路径
const ext = path.extname(file.name);
const newFileName = `${Date.now()}${ext}`;
file.path = path.join(__dirname, 'uploads', newFileName);
});
form.parse(req, (err, fields, files) => {
if (err) {
return res.status(500).send('文件上传失败');
}
console.log('文件已保存:', files);
res.send('文件上传成功');
});
});
- form.on(‘file’)
file 事件在文件上传完成时触发。你可以在这个事件中获取文件的详细信息,例如文件路径、大小等。
作用:在文件上传完成后进行处理,例如记录日志或进行后续操作。
位置:在文件上传完成后。
const formidable = require('formidable');
const path = require('path');
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
form.on('fileBegin', (name, file) => {
const ext = path.extname(file.name);
const newFileName = `${Date.now()}${ext}`;
file.path = path.join(__dirname, 'uploads', newFileName);
});
form.on('file', (name, file) => {
console.log('文件已保存:', file);
});
form.parse(req, (err, fields, files) => {
if (err) {
return res.status(500).send('文件上传失败');
}
res.send('文件上传成功');
});
});
总结
- 文件上传的主要实现:在 form.parse() 方法中完成。
- 文件路径和文件名的预处理:在 fileBegin 事件中完成。
- 文件上传完成后的处理:在 file 事件中完成。
- 最终结果处理:在 form.parse() 的回调函数中完成。
这里给一个完整上传图片,并判断是否图片,以及重新生成图片避免恶意代码
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
const uploadDir = path.join(__dirname, 'public', 'uploads');
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
form.on('fileBegin', (name, file) => {
console.log(`File upload started: ${name}`);
const ext = path.extname(file.originalFilename);
const new_file_name = `${Date.now()}${ext}`;
file.path = path.join(uploadDir, new_file_name); // 设置目标路径
});
form.parse(req, async (err, fields, files) => {
if (err) {
console.error('Formidable parse error:', err);
return res.status(500).send('文件上传失败');
}
console.log('接收到的文件:', files);
if (!files.photo || !Array.isArray(files.photo) || files.photo.length === 0) {
console.error('未接收到文件或文件数组为空');
return res.status(400).send('未接收到文件');
}
const file = files.photo[0]; // files.photo 是一个数组
const tempPath = file.filepath; // 临时路径
const targetPath = file.path; // 目标路径
if(!file.mimetype.startsWith('image/'))
{
console.error('上传的文件不是图片');
fs.unlink(tempPath,()=>{});
return res.status(400).send('只允许上传图片');
}
console.log(`Copying file from ${tempPath} to ${targetPath}`);
// 使用 sharp重新生成图片
try{
await sharp(tempPath)
.toFormat('png')
.toFile(targetPath);
console.log(`图片已经处理和保存在:${targetPath}`);
//删除临时文件
fs.unlink(tempPath,(unlinkErr)=>{
if(unlinkErr)
{
console.error('删除临时图片失败:',unlinkErr);
}
});
//这里是生成获取表单的值及上传的图片的相对路径,然后存入数据库,先写在对象中再存入
const dataToSave={
name:fields.name[0],
email:fields.email[0],
photoPath:path.relative(__dirname,targetPath) //获取相对目录的图片路径
};
console.log('数据对象:',dataToSave);
res.send('文件上传成功');
}catch(sharpErr)
{
console.log('图片处理失败:',sharpErr);
res.status(500).send('图片处理失败,请上传正确的图片');
}
});
form.on('error', (err) => {
console.error('Formidable 错误:', err);
res.status(500).send('文件上传失败');
});
});

3万+

被折叠的 条评论
为什么被折叠?



