Висловити res.sendfile викидання забороненої помилки


160

У мене є цей код:

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)

Хтось може мені сказати, чому це може бути?


3
Я вважаю, це через відносний шлях; "../" вважається шкідливим. Спочатку вирішіть місцевий шлях, а потім зателефонуйтеres.sendfile
— Джо

Як вирішити місцевий шлях?

4
path.resolveслід робити те, що потрібно.
— Джо

1
Це і вдалося. Хочете пропустити це як відповідь?

Відповіді:


286

Я вважаю, це через відносний шлях; "../" вважається шкідливим. Спочатку вирішіть місцевий шлях, а потім зателефонуйте res.sendfile. Ви можете path.resolveзаздалегідь вирішити шлях .

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

31
більше деталей тут буде корисно для новачків, як я
— Адам Уайт

5
Експрес розглядає відносні шляхи sendfileяк погані. Якщо ви не вказали rootпараметр каталогу, як це видно тут: github.com/visionmedia/express/isissue/1465
— Джо

2
var шлях = вимагати ('шлях');
— Метт Харрісон

1
так, остаточний код!
— SuperUberDuper

2
Оновлення @MattHarrison ES6, для імпорту пакетів, constнадається перевагуvar
— Nino

39

Ця відповідь збирає інформацію з інших відповідей / коментарів.

Це залежить від того, чи хочете ви включити щось відносно робочого каталогу (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')може бути перша спроба хакера).


1
Як новачок я хочу знати, як сюди потрапив хакерський сценарій?
— bharath muppa

2
Якщо ви випадково дозволите користувачеві ввести шлях до файлу, який він бажає завантажити, він може завантажити будь-який файл у вашій системі (я наводив приклад приватного ключа ssh - це дасть їм можливість претендувати на ваш ПК ( людина-посередині тощо)). Наявність .. обмеження забороняє цю можливість, оскільки доступ до файлів із веб-сайту можна отримати тільки.
— derekdreery

30

Документація " Експрес" пропонує зробити це по-іншому, і, на мою думку, це має більше сенсу пізніше, ніж поточне рішення.

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

Здається, що кореневий параметр задається ./як кореневий каталог вашого проекту. Тож я не можу повністю сказати, де ви подаєте файл стосовно кореня проекту, але якщо там знаходиться ваша папка temp, ви можете встановити ./tempкорінь для файлу, який ви надсилаєте.


1
Це правда, але він використовує sendFile (з великої літери F, підтримується Express v4.8.0 і далі) замість старого sendfile, який використовував ОП. Просто кажу ... =]
— RemyNL

Ааа ... гарний улов. Я не помітив цієї невеликої різниці. Мені також цікаво, чи вибрана відповідь працює не тому, що вона використовує, .sendfileа тому, що повністю покладається на щось інше (шлях). Дякуємо, що вказали на це.
— tenor528

Простий і ефективний. Дякую! Це працювало для мене чудово!
— Емануела Кольта
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.