res.sendFile chemin absolu

137

Si je fais un

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

alors je reçois un avertissement de la console du serveur

express obsolète res.sendfile: à utiliser à la res.sendFileplace

mais cela fonctionne bien du côté client.

Mais quand je le change en

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

J'obtiens une erreur

TypeError: le chemin doit être absolu ou spécifier la racine de res.sendFile

et index1.htmln'est pas rendu.

Je suis incapable de comprendre quel est le chemin absolu. J'ai un publicrépertoire au même niveau que server.js. Je fais res.sendFiledu avec server.js. J'ai aussi déclaréapp.use(express.static(path.join(__dirname, 'public')));

Ajout de ma structure de répertoires:

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

Quel est le chemin absolu à spécifier ici?

J'utilise Express 4.x.

Toast Kaya
la source
Si vous utilisez le express.staticmiddleware pour servir votre annuaire public, pourquoi avez-vous besoin res.sendFiled'envoyer public/index1.html?
Mike S
1
J'appelle res.sendFilede l'intérieur app.get('/', function(req, res){res.sendFile("...")})pour l'envoyer à la demande.
Kaya Toast

Réponses:

311

Le express.staticmiddleware est séparé de res.sendFile, donc l'initialiser avec un chemin absolu vers votre publicrépertoire ne fera rien res.sendFile. Vous devez utiliser un chemin absolu directement avec res.sendFile. Il existe deux façons simples de le faire:

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

Remarque: __dirname renvoie le répertoire dans lequel se trouve le script en cours d'exécution. Dans votre cas, il ressemble à server.jsis app/. Alors, pour se rendre à public, vous aurez besoin de retour à un premier niveau: ../public/index1.html.

Remarque: pathest un module intégré qui doit être required pour que le code ci-dessus fonctionne:var path = require('path');

Mike S
la source
14
res.sendFile('../public/index.html', {root: __dirname});fonctionne aussi et c'est plus court
Fabien Sa
Travailler avec express et webstorm ide: il n'y a pas d'erreur console.log(path.join(__dirname, '../public', 'index.html'));mais res.sendFile(path.join(__dirname, '../public', 'index.html'));ne fonctionne qu'avec var path = require('path');
Quake1TF
N'existe-t-il aucun moyen de prédéfinir le chemin absolu afin qu'il puisse être utilisé dans sendFile?
eran otzap
4
res.sendFile('../public/index.html', {root: __dirname});ne fonctionne pas (plus), car il renvoie 403 Forbidden en raison du dépassement de la racine. Faites res.sendFile('public/index.html', {root: path.dirname(__dirname)});plutôt.
Trevor Robinson
48

Essayez plutôt ceci:

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

Cela a fonctionné pour moi. la racine: __ dirname prendra l'adresse où se trouve server.js dans l'exemple ci-dessus, puis pour accéder à l'index1.html (dans ce cas), le chemin renvoyé consiste à accéder au répertoire où se trouve le dossier public.

Kshitij Choudhary
la source
Pourquoi cette option n'est-elle pas documentée?
timkay le
9
res.sendFile( __dirname + "/public/" + "index1.html" );

__dirnamegérera le nom du répertoire dans lequel server.jsréside le script ( ) en cours d'exécution .

SOuřaan Gřg
la source
Cette solution était assez simple Merci pour l'aide. Je me demande pourquoi les gens recommandent d'utiliser le package «path» pour faire de même.
Le troisième
3
@TheThird je suppose, utiliser le pathrend indépendant du système d' exploitation .
kmonsoor
7

Une alternative qui n'a pas encore été répertoriée et qui a fonctionné pour moi consiste simplement à utiliser path.resolvedes chaînes séparées ou une seule avec le chemin complet:

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

Ou

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

(Nœud v6.10.0)

Idée provenant de https://stackoverflow.com/a/14594282/6189078

Phil Gibbins
la source
6

Sur la base des autres réponses, voici un exemple simple de la manière d'accomplir l'exigence la plus courante:

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)

Cela sert également de moyen simple de répondre avec index.html à chaque demande , car j'utilise une étoile *pour attraper tous les fichiers qui n'ont pas été trouvés dans votre répertoire statique (public); qui est le cas d'utilisation le plus courant pour les applications Web. Remplacez par /pour renvoyer l'index uniquement dans le chemin racine.

Jaime Gómez
la source
Agréable. Sympa et succinct.
lharby le
5

Je l'ai essayé et ça marche.

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

process.cwd() renvoie le chemin absolu de votre projet.

Ensuite :

res.sendFile( `${process.cwd()}/public/index1.html` );
Abdennour TOUMI
la source
3

Une autre façon de faire cela en écrivant moins de code.

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

app.get('/', function(req, res) {
   res.sendFile('index.html');
});
Tim Anishere
la source
5
Cela génère "TypeError: le chemin doit être absolu ou spécifier la racine de res.sendFile"
GreenAsJade
1

vous pouvez utiliser send au lieu de sendFile pour ne pas faire face à une erreur! cela fonctionne vous aidera!

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

pour indiquer au navigateur que votre réponse est de type PDF

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

si vous voulez que ce fichier s'ouvre immédiatement sur la même page après le téléchargement de l'utilisateur, écrivez «en ligne» à la place de la pièce jointe dans le code ci-dessus.

res.send(data)
Aref.T
la source
0

Si vous souhaitez configurer cela une fois et l'utiliser partout, configurez simplement votre propre middleware. Lorsque vous configurez votre application, utilisez ce qui suit pour définir une nouvelle fonction sur l'objet de réponse:

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

Ensuite, utilisez-le comme suit:

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

J'utilise Node.Js et j'ai eu le même problème ... J'ai résolu simplement en ajoutant un '/' au début de chaque script et un lien vers un fichier statique css.

Avant:

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

Après:

<link rel="stylesheet" href="/assets/css/bootstrap/bootstrap.min.css">
Jackson D
la source
Vous devrez configurer le serveur statique express pour que cela fonctionne
Hum4n01d