无法使用node.js中的javascript在Windows中删除文件

我有下面的代码,试图删除Windows 7计算机上的文件:

// check if this item has an uploaded image file var imageFullPathName = __dirname + "/../public/images/" + req.params.itemId; logger.log("imageFullPathName = " + imageFullPathName); var normalizedPathName = path.normalize(imageFullPathName); logger.log("normalizedPathName = " + normalizedPathName); // delete the image if it exists fs.exists(normalizedPathName, function(exists) { console.log("Found the file: " + normalizedPathName); normalizedPathName = normalizedPathName.replace(/\\/g,"\\\\"); console.log("New path name = " + normalizedPathName); fs.unlink(normalizedPathName, function(err){ if (err){ console.error("Error in call to fs.unlink"); } }); }); 

我得到以下输出:

imageFullPathName = C:\ IronKey \ hes \ cscie-71 \ project \ medical-interchange \ routes /../ public / images / 5658e5612103cb2c41000006

normalizedPathName = C:\ IronKey \ hes \ cscie-71 \ project \ medical-interchange \ public \ images \ 5658e5612103cb2c41000006

新path名称= C:\\ IronKey \\ hes \\ cscie-71 \\ project \\ medical-interchange \\ public \\ images \\ 5658e5612103cb2c41000006

在调用fs.unlink时出错

有问题的文件确实存在,当我使用DOSshell寻找它。 不pipe我对新path名称做什么,我都不能删除文件。 如果我通过注释掉对normalizedPathName.replace()的调用而留下单斜杠的path,它仍然失败。 但是,如果我手动创build一个像这样的string它的作品:

fs.unlink(“c:\\ IronKey \\ hes \\ cscie-71 \\ project \\ medical-interchange \\ public \\ images \\ 5658e5612103cb2c41000006”,function(err){…

我该怎么做才能删除这个文件? 我完全难住。

我修改了如下所示的josh3736推荐的代码,但是我得到一个ENOENT错误。 该文件显然确实存在,因为我在编辑器中使用错误消息中报告的EXACT完整path名称打开它:

  // check if this item has an uploaded image file var imageFullPathName = path.join(__dirname, "../public/images", sanitize(req.params.itemId)); logger.log("imageFullPathName = " + imageFullPathName); fs.unlink(imageFullPathName, function(err){ //if (err.code != 'ENOENT'){ if (err){ logger.log("Error in call to fs.unlink", err); } else{ logger.log("No file found"); } logger.log("Delete Success"); }); 

错误消息如下:调用fs.unlink错误{[错误:ENOENT:没有这样的文件或目录,取消链接'C:\\ IronKey \\ hes \\ cscie-71 \\ project \\ medical-interchange \\公共\\ \\图像5658fd27fca1b3bc3d00000e']

这里有几个问题。

  1. 你盲目地信任用户input。 攻击者只需要请求一个itemId设置为类似于%2E%2E%2F%2E%2E%2F%2E%2E%2FWindows 。 Express会在req.params../../../Windows ,然后就是你的服务器。

    一般来说,记住在处理不可信input(以及通过HTTP传入的任何内容是不可信的)时要格外小心。 在这种情况下,使用像sanitize-filename这样的东西来确保input中没有调皮。

  2. fs.exists是一个反模式。 一些其他的进程可能会添加或删除您的调用之间exists的文件和下一步做的任何问题。 相反,无条件地调用unlink – 如果你得到err.code == 'ENOENT'的错误,文件不存在; 只是忽略错误。

  3. 为什么normalizedPathName = normalizedPathName.replace(/\\/g,"\\\\"); ? 你有一个有效的path,你是无效的( C:\foo\barC:\\foo\\bar ),所以当然是行不通的。

  4. 在组装path时,请使用path.join ,而不是string连接。 它将处理斜杠( \ vs / ),使您的代码可移植。

综合考虑这一点,

 var imageFullPathName = path.join( __dirname, "../public/images", sanitizeFilename(req.params.itemId) ); fs.unlink(imageFullPathName, function(err){ if (err) { if (err.code != 'ENOENT') { // handle actual errors here console.error("Error in call to fs.unlink", err); } // else there was no file, handle that if you need to } // else delete success, handle that if you need to }); 

既然你提到,即使在注释掉反斜杠replace行时,你的代码也会失败:

你的代码应该这样工作。 什么是实际的错误? 我第一次猜测会是一个权限问题。