res.sendFile绝对路径


137

如果我做一个

res.sendfile('public/index1.html'); 

然后我收到服务器控制台警告

表达已弃用res.sendfileres.sendFile改为使用

但它在客户端工作正常。

但是当我将其更改为

res.sendFile('public/index1.html');

我得到一个错误

TypeError:路径必须是绝对路径或将根目录指定为 res.sendFile

并且index1.html不呈现。

我无法弄清楚绝对路径是什么。我的public目录与处于同一级别server.js。我正在res.sendFile使用server.js。我也宣布app.use(express.static(path.join(__dirname, 'public')));

添加我的目录结构:

/Users/sj/test/
....app/
........models/
....public/
........index1.html

在此处指定的绝对路径是什么?

我正在使用Express4.x。


如果您使用express.static中间件来服务您的公共目录,为什么需要res.sendFile发送public/index1.html
Mike S

1
res.sendFile从内部打电话app.get('/', function(req, res){res.sendFile("...")})按需发送。
卡亚吐司2014年

Answers:


310

express.static中间件是独立的res.sendFile,所以用你的绝对路径初始化它public目录不会做任何事情res.sendFile。您需要直接使用绝对路径res.sendFile。有两种简单的方法可以做到这一点:

  1. res.sendFile(path.join(__dirname, '../public', 'index1.html'));
  2. res.sendFile('index1.html', { root: path.join(__dirname, '../public') });

注意: __dirname返回当前正在执行的脚本所在的目录。在您的情况下,它看起来像server.js在中app/。因此,要进入public,您首先需要退出一个级别:../public/index1.html

注意: path是一个内置模块,需要required才能使上述代码起作用:var path = require('path');


14
res.sendFile('../public/index.html', {root: __dirname});也有效,而且时间更短
Fabien Sa

使用express和webstorm ide:没有错误,console.log(path.join(__dirname, '../public', 'index.html'));res.sendFile(path.join(__dirname, '../public', 'index.html'));仅适用于 var path = require('path');
Quake1TF

没有办法预定义绝对路径,以便可以在sendFile中使用它吗?
艾兰·奥扎普

4
res.sendFile('../public/index.html', {root: __dirname});不起作用(不再),因为由于超出根目录而返回403禁止。做吧res.sendFile('public/index.html', {root: path.dirname(__dirname)});
特雷弗·罗宾逊

48

只需尝试以下方法:

res.sendFile('public/index1.html' , { root : __dirname});

这对我有用。root:__ dirname将使用上例中server.js所在的地址,然后到达index1.html(在本例中),返回的路径将到达公用文件夹所在的目录。


为什么未记录此选项?
timkay

9
res.sendFile( __dirname + "/public/" + "index1.html" );

此处__dirname将管理当前正在执行的脚本(server.js)所在目录的名称。


这个解决方案非常简单。感谢您的帮助。.我不知道为什么人们建议使用'path'包来做同样的事情。
3

3
我猜@TheThird,使用path使其独立于操作系统。
kmonsoor

7

尚未列出的对我有用的另一种选择是简单地使用path.resolve单独的字符串或仅使用整个路径之一:

// comma separated
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src', 'app', 'index.html') );
});

要么

// just one string with the path
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src/app/index.html') );
});

(节点v6.10.0)

创意源自https://stackoverflow.com/a/14594282/6189078


6

根据其他答案,这是一个如何满足最常见要求的简单示例:

const app = express()
app.use(express.static('public')) // relative path of client-side code
app.get('*', function(req, res) {
    res.sendFile('index.html', { root: __dirname })
})
app.listen(process.env.PORT)

这也是对每个请求使用index.html进行响应的一种简单方法,因为我使用星号*来捕获在静态(公共)目录中找不到的所有文件;这是网络应用最常见的用例。更改为/仅在根路径中返回索引。


真好 简洁明了。
拉比

5

我尝试了一下,它奏效了。

app.get('/', function (req, res) {
    res.sendFile('public/index.html', { root: __dirname });
});

4

process.cwd() 返回项目的绝对路径。

然后 :

res.sendFile( `${process.cwd()}/public/index1.html` );

3

减少编写代码的另一种方法。

app.use(express.static('public'));

app.get('/', function(req, res) {
   res.sendFile('index.html');
});

5
这将生成“ TypeError:路径必须是绝对路径或为res.sendFile指定根目录”
GreenAsJade

1

您可以使用send而不是sendFile,这样您就不会遇到错误!这项工程将为您提供帮助!

fs.readFile('public/index1.html',(err,data)=>{
if(err){
  consol.log(err);
}else {
res.setHeader('Content-Type', 'application/pdf');

告诉浏览器您的回复是PDF类型

res.setHeader('Content-Disposition', 'attachment; filename='your_file_name_for_client.pdf');

如果您希望该文件在用户下载后立即在同一页面上打开,请在上面的代码中写入“内联”而不是附件。

res.send(data)

0

如果您要设置一次并在各处使用它,只需配置自己的中间件。设置应用程序时,请使用以下命令在响应对象上定义新功能:

app.use((req, res, next) => {
  res.show = (name) => {
    res.sendFile(`/public/${name}`, {root: __dirname});
  };
  next();
});

然后按以下方式使用它:

app.get('/demo', (req, res) => {
  res.show("index1.html");
});

0

我使用Node.Js并遇到相同的问题...我解决了在每个脚本的开头添加“ /”并链接到CSS静态文件的问题。

之前:

<link rel="stylesheet" href="assets/css/bootstrap/bootstrap.min.css">

后:

<link rel="stylesheet" href="/assets/css/bootstrap/bootstrap.min.css">

您必须为此安装快速静态服务器
Hum4n01d
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.