无法使用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']
这里有几个问题。
-
你盲目地信任用户input。 攻击者只需要请求一个
itemId
设置为类似于%2E%2E%2F%2E%2E%2F%2E%2E%2FWindows
。 Express会在req.params
为../../../Windows
,然后就是你的服务器。一般来说,记住在处理不可信input(以及通过HTTP传入的任何内容是不可信的)时要格外小心。 在这种情况下,使用像sanitize-filename这样的东西来确保input中没有调皮。
-
fs.exists
是一个反模式。 一些其他的进程可能会添加或删除您的调用之间exists
的文件和下一步做的任何问题。 相反,无条件地调用unlink
– 如果你得到err.code == 'ENOENT'
的错误,文件不存在; 只是忽略错误。 -
为什么
normalizedPathName = normalizedPathName.replace(/\\/g,"\\\\");
? 你有一个有效的path,你是无效的(C:\foo\bar
→C:\\foo\\bar
),所以当然是行不通的。 -
在组装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
行时,你的代码也会失败:
你的代码应该这样工作。 什么是实际的错误? 我第一次猜测会是一个权限问题。