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.

Kaya Toast
quelle
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');

Mike S.
quelle
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.

Kshitij Choudhary
quelle
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.

SOuřaan Gřg
quelle
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

Phil Gibbins
quelle
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.

Jaime Gómez
quelle
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 });
});
Boms
quelle
4

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

Dann :

res.sendFile( `${process.cwd()}/public/index1.html` );
Abdennour TOUMI
quelle
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');
});
Tim Anishere
quelle
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)
Aref.T.
quelle
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");
});
danp
quelle
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">
Jackson D.
quelle
Sie müssten den statischen Express-Server einrichten, damit dies funktioniert
Hum4n01d