res.sendFile absoluter Pfad


137

Wenn ich a mache

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

dann bekomme ich eine Serverkonsolenwarnung

Express veraltet res.sendfile: Verwenden Sie res.sendFilestattdessen

aber es funktioniert gut auf der Client-Seite.

Aber wenn ich es ändere

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

Ich bekomme eine Fehlermeldung

TypeError: Pfad muss absolut sein oder root angeben res.sendFile

und index1.htmlwird nicht gerendert.

Ich kann nicht herausfinden, was der absolute Weg ist. Ich habe publicVerzeichnis auf der gleichen Ebene wie server.js. Ich mache das res.sendFilevon mit server.js. Ich habe auch erklärtapp.use(express.static(path.join(__dirname, 'public')));

Hinzufügen meiner Verzeichnisstruktur:

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

Was ist der absolute Pfad, der hier angegeben werden muss?

Ich benutze Express 4.x.


express.staticWarum müssen Sie res.sendFilesenden, wenn Sie die Middleware für Ihr öffentliches Verzeichnis verwenden public/index1.html?
Mike S

1
Ich rufe res.sendFilevon innen app.get('/', function(req, res){res.sendFile("...")})an, um es auf Anfrage zu senden.
Kaya Toast

Antworten:


310

Die express.staticMiddleware ist von getrennt res.sendFile, sodass das Initialisieren mit einem absoluten Pfad zu Ihrem publicVerzeichnis nichts bewirkt res.sendFile. Sie müssen einen absoluten Pfad direkt mit verwenden res.sendFile. Es gibt zwei einfache Möglichkeiten:

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

Hinweis: __dirname Gibt das Verzeichnis zurück, in dem sich das aktuell ausgeführte Skript befindet. In Ihrem Fall sieht es so aus, als ob server.jses sich in befindet app/. Um dorthin zu gelangen, publicmüssen Sie zuerst eine Ebene zurücksetzen : ../public/index1.html.

Hinweis: pathist ein integriertes Modul , das required sein muss, damit der obige Code funktioniert:var path = require('path');


14
res.sendFile('../public/index.html', {root: __dirname});funktioniert auch und es ist kürzer
Fabien Sa

Arbeiten mit Express und Webstorm ide: Ich habe keinen Fehler erhalten, console.log(path.join(__dirname, '../public', 'index.html'));sondern res.sendFile(path.join(__dirname, '../public', 'index.html'));arbeite nur mit var path = require('path');
Quake1TF

Gibt es keine Möglichkeit, den absoluten Pfad vorab zu definieren, damit er in sendFile verwendet werden kann?
eran otzap

4
res.sendFile('../public/index.html', {root: __dirname});funktioniert (nicht mehr), da es 403 Forbidden zurückgibt, weil es über die Wurzel hinausgeht. Tun Sie res.sendFile('public/index.html', {root: path.dirname(__dirname)});stattdessen.
Trevor Robinson

48

Versuchen Sie stattdessen Folgendes:

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

Das hat bei mir funktioniert. Der Name root: __ nimmt die Adresse an, an der sich server.js im obigen Beispiel befindet. Um dann zur Datei index1.html (in diesem Fall) zu gelangen, muss der zurückgegebene Pfad in das Verzeichnis gelangen, in dem sich der öffentliche Ordner befindet.


Warum ist diese Option nicht dokumentiert?
Timkay

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

Hier __dirnamewird der Name des Verzeichnisses verwaltet, in dem sich das aktuell ausgeführte Skript ( server.js) befindet.


Diese Lösung war ziemlich einfach. Vielen Dank für die Hilfe. Ich frage mich, warum die Leute empfehlen, das 'path'-Paket zu verwenden, um dasselbe zu tun.
Der dritte

3
@ TheThird Ich denke, mit pathmacht es os-unabhängig.
kmonsoor

7

Eine Alternative, die noch nicht aufgeführt ist und für mich funktioniert hat, besteht darin, path.resolveentweder separate Zeichenfolgen oder nur eine mit dem gesamten Pfad zu verwenden:

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

Oder

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

(Knoten v6.10.0)

Idee von https://stackoverflow.com/a/14594282/6189078


6

Basierend auf den anderen Antworten ist dies ein einfaches Beispiel dafür, wie die häufigste Anforderung erfüllt werden kann:

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)

Dies ist auch eine einfache Möglichkeit, auf jede Anfrage mit index.html zu antworten , da ich einen Stern verwende *, um alle Dateien abzufangen, die nicht in Ihrem statischen (öffentlichen) Verzeichnis gefunden wurden. Dies ist der häufigste Anwendungsfall für Web-Apps. Wechseln Sie zu /, um den Index nur im Stammpfad zurückzugeben.


Nett. Schön und prägnant.
lharby

5

Ich habe es versucht und es hat funktioniert.

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

4

process.cwd() Gibt den absoluten Pfad Ihres Projekts zurück.

Dann :

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

3

Eine andere Möglichkeit, dies zu tun, indem weniger Code geschrieben wird.

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

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

5
Dies erzeugt "TypeError: Pfad muss absolut sein oder root für res.sendFile angeben"
GreenAsJade

1

Sie können send anstelle von sendFile verwenden, damit Sie nicht mit Fehlern konfrontiert werden! das wird dir helfen!

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

um dem Browser mitzuteilen, dass Ihre Antwort ein PDF-Typ ist

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

Wenn Sie möchten, dass diese Datei sofort auf derselben Seite geöffnet wird, nachdem der Benutzer sie heruntergeladen hat, schreiben Sie 'inline' anstelle des Anhangs im obigen Code.

res.send(data)

0

Wenn Sie dies einmal einrichten und überall verwenden möchten, konfigurieren Sie einfach Ihre eigene Middleware. Verwenden Sie beim Einrichten Ihrer App Folgendes, um eine neue Funktion für das Antwortobjekt zu definieren:

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

Verwenden Sie es dann wie folgt:

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

0

Ich benutze Node.Js und hatte das gleiche Problem ... Ich habe es gelöst, indem ich am Anfang jedes Skripts ein '/' hinzugefügt und auf eine statische CSS-Datei verlinkt habe.

Vor:

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

Nach dem:

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

Sie müssten den statischen Express-Server einrichten, damit dies funktioniert
Hum4n01d
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.