Express res.sendfile 抛出禁止错误

我有这个密码:

res.sendfile( '../../temp/index.html' )

然而,它抛出了这个错误:

Error: Forbidden
at SendStream.error (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/send/lib/send.js:145:16)
at SendStream.pipe (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/send/lib/send.js:307:39)
at ServerResponse.res.sendfile (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/response.js:339:8)
at exports.boot (/Users/Oliver/Development/Personal/Reader/server/config/routes.js:18:9)
at callbacks (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:161:37)
at param (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:33:10)
at next (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/connect/lib/proto.js:199:15)

有人能告诉我这是为什么吗?

83330 次浏览

我相信这是因为相对路径。./”被视为恶意。首先解析本地路径,然后调用 res.sendfile。您可以事先使用 path.resolve解析路径。

var path = require('path');
res.sendFile(path.resolve('temp/index.html'));

这个答案收集了其他答案/评论的信息。

这取决于您是否希望包含与进程工作目录(cwd)或文件目录相关的内容。它们都使用 path.resolve函数(将 var path = require('path')放在文件的顶部)。

  • 相对于 cwd: path.resolve('../../some/path/to/file.txt');
  • 相对于文件: path.resolve(__dirname+'../../some/path/to/file.txt');

从@Joe 的评论中读到的链接来看,如果你接受用户对路径的输入(例如 sendfile('../.ssh/id_rsa')可能是黑客的第一次尝试) ,那么相对路径就是一个安全风险。

快速文档建议使用不同的方法,在我看来,它比当前的解决方案更有意义。

res.sendFile('index.html', {root: './temp'});

Root 选项似乎将 ./设置为项目的根目录。所以我不能完全告诉您的文件在哪里相对于项目根目录,但是如果您的临时文件夹在那里,您可以设置 ./temp作为您正在发送的文件的根目录。

此外,还可以使用 path.join

const path = require("path");


router.get("/", (req, res) => {
let indexPath = path.join(__dirname, "../public/index.html");
res.sendFile(indexPath);
});