【问题标题】:Express res.sendfile throwing forbidden errorExpress res.sendfile 抛出禁止错误
【发布时间】:2023-04-03 06:59:01
【问题描述】:

我有这个代码:

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)

谁能告诉我为什么会这样?

【问题讨论】:

  • 我相信是因为相对路径; “../”被认为是恶意的。先解析本地路径,再调用res.sendfile
  • 本地路径如何解析?
  • path.resolve 应该做你需要的。
  • 做到了。想把它作为答案吗?

标签: node.js express


【解决方案1】:

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

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

【讨论】:

  • 对于像我这样的新手来说,更多细节会很方便
  • Express 认为sendfile 中的相对路径不好。除非您指定 root 目录参数,如下所示:github.com/visionmedia/express/issues/1465
  • var path = require('path');
  • 是的,最后的代码!!
  • @MattHarrison ES6 更新,对于包导入,const 优先于 var
【解决方案2】:

此答案收集来自其他答案/cmets 的信息。

这取决于您是否要包含与进程工作目录(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') 可能是黑客的第一次尝试)。

【讨论】:

  • 作为一个新手我想知道黑客场景是怎么来的?
  • 如果你不小心让用户输入了他们想要下载的文件的路径,他们可以下载你系统上的任何文件(我给出了一个 ssh 私钥的例子——这会给他们能够伪装成您的 PC(中间人等))。具有 .. 限制不允许这种可能性,因为只能访问网站中的文件。
【解决方案3】:

Express documentation 建议以不同的方式进行处理,在我看来,它比当前的解决方案更有意义。

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

root 选项似乎将./ 设置为项目的根目录。所以我无法完全确定您的文件与项目根目录的关系,但如果您的临时文件夹在那里,您可以将./temp 设置为您要发送的文件的根目录。

【讨论】:

  • 这是真的,但它使用 sendFile(大写 F,Express v4.8.0 及更高版本支持)而不是 OP 使用的较旧的 sendfile。只是说... =]
  • 啊……不错。我没有注意到这个小区别。我还想知道所选答案是否有效不是因为它使用.sendfile,而是因为它完全依赖于其他东西(路径)。感谢您指出这一点。
  • 简单高效。谢谢!这对我来说非常有用!
【解决方案4】:

另外,您可以使用path.join

const path = require("path");

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

【讨论】:

    猜你喜欢
    • 2015-06-20
    • 1970-01-01
    • 2020-09-04
    • 2014-11-08
    • 2014-11-29
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多