res.sendFile абсолютний шлях


137

Якщо я роблю

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

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

вираз застарілий res.sendfile: res.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

Який абсолютний шлях слід вказати тут?

Я використовую Express 4.x.


Якщо ви використовуєте express.staticпроміжне програмне забезпечення для обслуговування свого загальнодоступного каталогу, чому його потрібно res.sendFileнадсилати public/index1.html?
Майк 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це вбудований модуль, який повинен бути required, щоб вищевказаний код працював:var path = require('path');


14
res.sendFile('../public/index.html', {root: __dirname});також працює, і це коротше
Fabien Sa

Робота з експресом та ідеєю веб-штормів: не помилилася, 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 Заборонено через перехід над коренем. Зробіть res.sendFile('public/index.html', {root: path.dirname(__dirname)});замість цього.
Тревор Робінсон

48

Просто спробуйте це замість цього:

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

Це працювало для мене. root: __ dirname візьме адресу, де server.js знаходиться у наведеному вище прикладі, а потім потрапить до index1.html (у цьому випадку) повернутий шлях - це потрапити до каталогу, де знаходиться загальнодоступна папка.


Чому цей варіант не задокументований?
темкай

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

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


Це рішення було досить прямо вперед. Дякую за допомогу. Цікаво, чому люди рекомендують використовувати пакет "шлях", щоб зробити те саме.
Третє

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.