表示res.send文件抛出禁止错误

149 node.js express

我有这个代码:

res.sendfile( '../../temp/index.html' )
Run Code Online (Sandbox Code Playgroud)

但是,它会抛出此错误:

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)
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*Joe 260

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

var path = require('path');
res.sendFile(path.resolve('temp/index.html'));
Run Code Online (Sandbox Code Playgroud)

  • 对于像我这样的新手来说,更多细节会很方便 (28认同)
  • Express认为`sendfile`中的相对路径是坏的.除非你指定`root`目录参数,如下所示:https://github.com/visionmedia/express/issues/1465 (4认同)
  • 那么最终的代码是什么样的呢? (3认同)
  • @MattHarrison ES6 更新,对于包导入,`const` 优于 `var` (3认同)
  • var path = require('path'); (2认同)

der*_*ery 38

这个答案汇集了其他答案/评论的信息.

这取决于您是否要包含与进程工作目录(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(男人在中间等)).由于只有来自网站的文件才能访问,因此限制不允许这种可能性. (2认同)

ten*_*528 28

Express文档建议做一个不同的方式,在我看来它使晚于当前的解决方案更有意义.

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

root选项似乎设置./为项目的根目录.因此,我无法完全确定您的文件位置与项目根目录相关,但如果您的临时文件夹存在,则可以将其设置./temp为您要发送的文件的根目录.