res.sendFile bezwzględna ścieżka


137

Jeśli zrobię

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

wtedy otrzymuję ostrzeżenie konsoli serwera

express przestarzałe res.sendfile: użyj res.sendFilezamiast tego

ale działa dobrze po stronie klienta.

Ale kiedy zmienię to na

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

Pojawia się błąd

TypeError: ścieżka musi być bezwzględna lub wskazywać root do res.sendFile

i index1.htmlnie jest renderowany.

Nie potrafię zrozumieć, jaka jest ścieżka absolutna. Mam publickatalog na tym samym poziomie co server.js. Robię res.sendFilez z server.js. Oświadczyłem równieżapp.use(express.static(path.join(__dirname, 'public')));

Dodawanie struktury katalogów:

/Users/sj/test/
....app/
........models/
....public/
........index1.html

Jaką ścieżkę bezwzględną należy określić w tym miejscu?

Używam Express 4.x.


Jeśli używasz express.staticoprogramowania pośredniego do obsługi katalogu publicznego, dlaczego musisz res.sendFilewysyłać public/index1.html?
Mike S

1
Dzwonię res.sendFilez wewnątrz, app.get('/', function(req, res){res.sendFile("...")})aby wysłać to na żądanie.
Kaya Toast

Odpowiedzi:


310

Oprogramowanie express.staticpośredniczące jest niezależne od oprogramowania res.sendFile, więc zainicjowanie go bezwzględną ścieżką do publickatalogu nic nie da res.sendFile. Musisz użyć ścieżki bezwzględnej bezpośrednio z res.sendFile. Można to zrobić na dwa proste sposoby:

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

Uwaga: __dirname zwraca katalog, w którym znajduje się aktualnie wykonywany skrypt. W twoim przypadku wygląda na to, że się w nim server.jsznajduje app/. Tak więc, aby dostać się public, trzeba wycofać się pierwszy o jeden poziom: ../public/index1.html.

Uwaga: pathto wbudowany moduł, który musi być required, aby powyższy kod działał:var path = require('path');


14
res.sendFile('../public/index.html', {root: __dirname});też działa i jest krótszy
Fabien Sa

Praca z ideą Express i Webstorm: nie wystąpił błąd, console.log(path.join(__dirname, '../public', 'index.html'));ale res.sendFile(path.join(__dirname, '../public', 'index.html'));działa tylko z var path = require('path');
Quake1TF

Czy nie ma sposobu, aby wstępnie zdefiniować ścieżkę bezwzględną, aby można było jej użyć w sendFile?
eran otzap

4
res.sendFile('../public/index.html', {root: __dirname});nie działa (już), ponieważ zwraca 403 Forbidden z powodu przekroczenia katalogu głównego. res.sendFile('public/index.html', {root: path.dirname(__dirname)});Zamiast tego zrób .
Trevor Robinson

48

Zamiast tego spróbuj tego:

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

To zadziałało dla mnie. root: __ dirname weźmie adres, w którym znajduje się server.js w powyższym przykładzie, a następnie, aby dostać się do index1.html (w tym przypadku), zwrócona ścieżka oznacza przejście do katalogu, w którym znajduje się folder publiczny.


Dlaczego ta opcja nie jest udokumentowana?
timkay

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

gdzie __dirnamebędzie zarządzać nazwą katalogu, w którym znajduje się aktualnie wykonywany skrypt ( server.js).


To rozwiązanie było całkiem proste. Dzięki za pomoc ... Zastanawiam się, dlaczego ludzie zalecają używanie pakietu „path”, aby zrobić to samo.
Trzeci

3
@TheThird wydaje mi się, że użycie pathczyni go niezależnym od systemu operacyjnego .
kmonsoor

7

Alternatywą, która nie została jeszcze wymieniona, a która działała dla mnie, jest po prostu użycie path.resolveoddzielnych ciągów lub tylko jednego z całą ścieżką:

// comma separated
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src', 'app', 'index.html') );
});

Lub

// just one string with the path
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src/app/index.html') );
});

(Węzeł v6.10.0)

Pomysł pochodzi z https://stackoverflow.com/a/14594282/6189078


6

Opierając się na innych odpowiedziach, jest to prosty przykład, jak spełnić najczęstsze wymaganie:

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)

To również podwaja się jako prosty sposób odpowiadania za pomocą index.html na każde żądanie , ponieważ używam gwiazdki *do wyłapywania wszystkich plików, które nie zostały znalezione w Twoim statycznym (publicznym) katalogu; co jest najczęstszym przypadkiem użycia aplikacji internetowych. Zmień na, /aby zwrócić indeks tylko w ścieżce głównej.


Miły. Miło i zwięźle.
lharby

5

Spróbowałem tego i zadziałało.

app.get('/', function (req, res) {
    res.sendFile('public/index.html', { root: __dirname });
});

4

process.cwd() zwraca bezwzględną ścieżkę projektu.

Następnie :

res.sendFile( `${process.cwd()}/public/index1.html` );

3

Można to zrobić w inny sposób, pisząc mniej kodu.

app.use(express.static('public'));

app.get('/', function(req, res) {
   res.sendFile('index.html');
});

5
To generuje "TypeError: path musi być bezwzględna lub określać katalog główny res.sendFile"
GreenAsJade

1

możesz użyć send zamiast sendFile, więc nie napotkasz błędu! to działa pomoże!

fs.readFile('public/index1.html',(err,data)=>{
if(err){
  consol.log(err);
}else {
res.setHeader('Content-Type', 'application/pdf');

za poinformowanie przeglądarki, że Twoja odpowiedź to typ PDF

res.setHeader('Content-Disposition', 'attachment; filename='your_file_name_for_client.pdf');

jeśli chcesz, aby ten plik otwierał się natychmiast na tej samej stronie po pobraniu go przez użytkownika. napisz „inline” zamiast załącznika w powyższym kodzie.

res.send(data)

0

Jeśli chcesz to skonfigurować raz i używać go wszędzie, po prostu skonfiguruj własne oprogramowanie pośrednie. Podczas konfigurowania aplikacji użyj następujących elementów, aby zdefiniować nową funkcję w obiekcie odpowiedzi:

app.use((req, res, next) => {
  res.show = (name) => {
    res.sendFile(`/public/${name}`, {root: __dirname});
  };
  next();
});

Następnie użyj go w następujący sposób:

app.get('/demo', (req, res) => {
  res.show("index1.html");
});

0

Używam Node.Js i miałem ten sam problem ... Rozwiązałem po prostu dodanie „/” na początku każdego skryptu i łącze do statycznego pliku css.

Przed:

<link rel="stylesheet" href="assets/css/bootstrap/bootstrap.min.css">

Po:

<link rel="stylesheet" href="/assets/css/bootstrap/bootstrap.min.css">

Aby to działało, musiałbyś skonfigurować ekspresowy serwer statyczny
Hum4n01d
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.