【问题标题】:In a NodeJS / Express (& multer) attachment upload utility, how to handle API delete requests?在 NodeJS / Express (& multer) 附件上传实用程序中,如何处理 API 删除请求?
【发布时间】:2020-07-20 16:46:32
【问题描述】:

以下是一个基本的文件上传实用程序。它可以令人满意地处理 React / Axios API POST。文件上传到服务器根目录下的~uploads 文件夹。如何为其添加 API DELETE 处理能力?设想一个用例,其中用户将附件上传到博客文章,然后从博客文章中删除附件。在查找示例时遇到问题。

var cors = require('cors');
var express = require('express');
var multer = require('multer')

var app = express();
app.use(cors());

// Parse JSON bodies (as sent by API clients)
app.use(express.json());

var storage = multer.diskStorage(
{
    destination: function (req, file, cb)
    {
        cb(null, 'fileuploads');
    },
    filename: function (req, file, cb)
    {
        cb(null, file.originalname );
    }
})

var upload = multer({ storage: storage }).array('file')

app.post('/upload',function(req, res)
{
    upload(req, res, function (err) 
    {
        if (err instanceof multer.MulterError)
        {
            return res.status(500).json(err)
        }
        else if (err)
        {
            return res.status(500).json(err)
        }
        return res.status(200).send(req.file)
    })
});

app.listen(8001, function() {

    console.log('App running on port 8001');

});

编辑:

app.delete(...)修改为以下,成功删除文件但大约一分钟后在控制台中抛出此错误:[Error: ENOENT: no such file or directory, unlink '<PATH VALUE>']

app.delete('/writer/:file_to_delete', async (req, res) =>
{
    const path = 'assets/uploads/' + req.params.targetFile;

    console.log(path);

    try
    {
        fs.unlink(path)
        // NOTE: `fs.unlinkSync(path)` does the same thing
        console.log('File deleted!');

        return res.status(200);
    }
    catch(err)
    {
        console.error(err)
        return res.status(500).json(err)
    }
});

【问题讨论】:

  • 使用fs模块从文件系统中删除文件并从http客户端监听app.delete方法。
  • @marc, fs.unlinkSync(path) 成功,但随后抛出了[Error: ENOENT: no such file or directory, unlink '<PATH>。它做了某种类型的双重检查。关于如何避免的任何线索?
  • 您试图删除的文件不存在。发布您的代码!
  • 谢谢。上面的编辑中发布的代码。请注意,最初并不是该文件不存在。磁盘上有一个文件通过fs.unsync(...) 成功删除。但是一分钟后它会抛出该错误,因此它会再次尝试查找文件。
  • 问题是return res.status(200) 的末尾没有send()。这有效:return res.status(200).send({data: req.params.file_name + ' deleted'});.

标签: node.js rest express multer delete-file


【解决方案1】:

我找到了前进的道路。代码如下,但我很高兴听到更好的方法:

// NOTE: `file_name` values are obfuscated and uniquely generated by the client.
// The actual file name is in data storage.
app.post('/delete/:file_name', (req, res) =>
{
    const theFile = 'attachments/' + req.params.file_name;

    var resultHandler = function(err) { 
        if(err) {
           console.log("file delete failed", err);
           return res.status(500).json(err)
        }
        console.log("file deleted");
        return res.status(200).send({data: req.params.file_name + ' deleted'});
    }
    
    fs.unlinkSync(theFile, resultHandler);
});

【讨论】:

  • 请记住,如果他知道文件名,每个人都可以删除“附件”目录中的任何文件。
  • 在这种情况下,硬盘驱动器上的文件名被混淆,真正的文件名仅在数据存储中可用。如果有更好的方法,我愿意改变。
  • 事件如果它们被混淆,如果我知道任何有效值,我可以删除文件。如果它很关键,你应该更好地应用一些“用户权限”逻辑来防止未经授权的删除,比如数据库检查哪个用户拥有哪个文件
  • 注意 - 也证明用户登录得太正确或者是过度杀伤?
  • 如果没有登录,我将拒绝对 API 的所有操作。无论用户正在尝试什么。旁注我注意到您在代码 sn-p 中的评论:“file_name 值被混淆并由客户端唯一生成。” -> 从来没有!!!信任一个客户端,更好的方式应该是通过上传部分在服务器端生成一个UUID并将这个uuid返回给客户端
猜你喜欢
  • 1970-01-01
  • 2016-08-04
  • 2018-07-21
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多