Ekspresowe wyrzucanie res.sendfile zabronione błąd


160

Mam ten kod:

res.sendfile( '../../temp/index.html' )

Jednak wyrzuca ten błąd:

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)

Czy ktoś może mi powiedzieć, dlaczego tak się dzieje?


3
Uważam, że dzieje się tak z powodu względnej ścieżki; „../” jest uważany za złośliwy. Najpierw ustal lokalną ścieżkę, a następnie zadzwońres.sendfile
Joe

Jak rozwiązujesz lokalną ścieżkę?

4
path.resolvepowinien zrobić to, czego potrzebujesz.
Joe

1
Zrobiło to. Chcesz to pominąć jako odpowiedź?

Odpowiedzi:


286

Uważam, że dzieje się tak z powodu względnej ścieżki; „../” jest uważany za złośliwy. Najpierw ustal ścieżkę lokalną, a następnie zadzwoń res.sendfile. Możesz wcześniej rozwiązać ścieżkę path.resolve.

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

31
więcej szczegółów przydałoby się tutaj nowicjuszom takim jak ja
Adam Waite

5
Express uważa ścieżki względne sendfileza złe. Chyba że określisz rootparametr katalogu, jak widać tutaj: github.com/visionmedia/express/issues/1465
Joe

2
var path = require ('path');
Matt Harrison,

1
tak, ostateczny kod !!
SuperUberDuper

2
Aktualizacja @MattHarrison ES6 do importu pakietów constjest preferowana nadvar
Nino Filiu

39

Ta odpowiedź zbiera informacje z innych odpowiedzi / komentarzy.

Zależy to od tego, czy chcesz dołączyć coś odnoszącego się do katalogu roboczego procesu (cwd), czy katalogu plików. Oba używają path.resolvefunkcji (umieść var path = require('path')na początku pliku.

  • w stosunku do cwd: path.resolve('../../some/path/to/file.txt');
  • względem pliku: path.resolve(__dirname+'../../some/path/to/file.txt');

Czytając link z komentarza @ Joe, wydaje się, że ścieżki względne stanowią zagrożenie bezpieczeństwa, jeśli akceptujesz dane wejściowe użytkownika dla ścieżki (np. sendfile('../.ssh/id_rsa') Może to być pierwsza próba hakera).


1
Jako nowicjusz chcę wiedzieć, jak doszło do scenariusza hakera?
bharath muppa

2
Jeśli przypadkowo pozwolisz użytkownikowi wprowadzić ścieżkę do pliku, który chce pobrać, może pobrać dowolny plik z twojego systemu (podałem przykład klucza prywatnego ssh - który dałby im możliwość udawania twojego komputera ( człowiek pośrodku itp.)). Ograniczenie ... uniemożliwia taką możliwość, ponieważ można uzyskać dostęp tylko do plików ze strony internetowej.
derekdreery

30

Dokumentacja Express sugeruje zrobienie tego w inny sposób i moim zdaniem ma to większy sens później niż obecne rozwiązanie.

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

Wydaje się, że opcja root jest ustawiona ./jako katalog główny twojego projektu. Dlatego nie mogę w pełni określić, gdzie znajduje się plik w stosunku do katalogu głównego projektu, ale jeśli znajduje się tam folder tymczasowy, możesz ustawić ./tempjako katalog główny wysyłanego pliku.


1
To prawda, ale używa sendFile (duże F, obsługiwane przez Express v4.8.0 i nowsze) zamiast starszego pliku wysyłania, którego używał OP. Tylko mówię ... =]
RemyNL

Ahh ... dobry chwyt. Nie zauważyłem tej małej różnicy. Zastanawiam się też, czy wybrana odpowiedź działa nie dlatego, że używa, .sendfileale dlatego, że polega na czymś zupełnie innym (ścieżce). Dziękuję za zwrócenie uwagi.
tenor 528

Prosty i skuteczny. Dziękuję Ci! To zadziałało dla mnie idealnie!
Emanuela Colta
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.