res.sendFile абсолютный путь

137

Если я сделаю

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

тогда я получаю предупреждение консоли сервера

Экспресс устарел res.sendfile: используйте res.sendFileвместо

но он прекрасно работает на стороне клиента.

Но когда я изменяю это на

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

Я получаю ошибку

TypeError: путь должен быть абсолютным или указывать root на 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

Какой абсолютный путь должен быть указан здесь?

Я использую Express 4.x.

Тост кая
источник
Если вы используете express.staticпромежуточное ПО для обслуживания общедоступного каталога, зачем вам res.sendFileотправлять public/index1.html?
Mike S
1
Я звоню res.sendFileизнутри, app.get('/', function(req, res){res.sendFile("...")})чтобы отправить по требованию.
Кая Тост

Ответы:

311

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это встроенный модуль, который необходимо выполнить requireдля работы приведенного выше кода: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?
eran otzap
4
res.sendFile('../public/index.html', {root: __dirname});не работает (больше), так как возвращает 403 Forbidden из-за превышения корня. Делай res.sendFile('public/index.html', {root: path.dirname(__dirname)});вместо этого.
Тревор Робинсон,
48

Просто попробуйте это вместо:

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

Это сработало для меня. корень: __dirname возьмет адрес, где находится server.js в приведенном выше примере, а затем, чтобы добраться до index1.html (в данном случае), возвращаемый путь - это каталог, в котором находится общая папка.

Кшитий Чоудхары
источник
Почему этот вариант не задокументирован?
Тимкай
9
res.sendFile( __dirname + "/public/" + "index1.html" );

where __dirnameбудет управлять именем каталога, в котором находится исполняемый в данный момент script ( server.js).

SOuřaan Gřg
источник
Это решение было довольно простым. Спасибо за помощь. Интересно, почему люди рекомендуют использовать пакет «path», чтобы сделать то же самое.
The Third
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 на каждый запрос , потому что я использую звездочку, *чтобы перехватить все файлы, которые не были найдены в вашем статическом (общедоступном) каталоге; что является наиболее распространенным вариантом использования веб-приложений. Измените значение на, /чтобы вернуть индекс только в корневом пути.

Хайме Гомес
источник
Ницца. Красиво и лаконично.
lharby
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)
Aref.T
источник
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");
});
danp
источник
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