Висловити 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.