node.js TypeError: le chemin doit être absolu ou spécifier la racine de res.sendFile [échec de l'analyse JSON]


152

[ajouter] Donc mon prochain problème est que lorsque j'essaye d'ajouter une nouvelle dépendance (npm install --save socket.io). Le fichier JSON est également valide. J'obtiens cette erreur: Échec de l'analyse de json

npm ERR! Unexpected string
npm ERR! File: /Users/John/package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
npm ERR! 
npm ERR! This is not a bug in npm.
npm ERR! Tell the package author to fix their package.json file. JSON.parse 

J'ai donc essayé de comprendre pourquoi cette erreur était de retour. Tous les fichiers (HTML, JSON, JS) se trouvent dans le même dossier sur mon bureau. J'utilise node.js et socket.io

Ceci est mon fichier JS:

var app = require('express')();
var http = require('http').Server(app);

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

http.listen(3000,function(){
    console.log('listening on : 3000');
});

Voici ce qui est retourné:

MacBook-Pro:~ John$ node /Users/John/Desktop/Chatapp/index.js 
listening on : 3000
TypeError: path must be absolute or specify root to res.sendFile
    at ServerResponse.sendFile (/Users/John/node_modules/express/lib/response.js:389:11)
    at /Users/John/Desktop/Chatapp/index.js:5:7
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at next (/Users/John/node_modules/express/lib/router/route.js:100:13)
    at Route.dispatch (/Users/John/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at /Users/John/node_modules/express/lib/router/index.js:234:24
    at Function.proto.process_params (/Users/John/node_modules/express/lib/router/index.js:312:12)
    at /Users/John/node_modules/express/lib/router/index.js:228:12
    at Function.match_layer (/Users/John/node_modules/express/lib/router/index.js:295:3)
TypeError: path must be absolute or specify root to res.sendFile
    at ServerResponse.sendFile (/Users/John/node_modules/express/lib/response.js:389:11)
    at /Users/John/Desktop/Chatapp/index.js:5:7
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at next (/Users/John/node_modules/express/lib/router/route.js:100:13)
    at Route.dispatch (/Users/John/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at /Users/John/node_modules/express/lib/router/index.js:234:24
    at Function.proto.process_params (/Users/John/node_modules/express/lib/router/index.js:312:12)
    at /Users/John/node_modules/express/lib/router/index.js:228:12
    at Function.match_layer (/Users/John/node_modules/express/lib/router/index.js:295:3)

Réponses:


331

L'erreur est assez claire, vous devez spécifier un chemin absolu (au lieu d'un chemin relatif) et / ou défini rootdans l'objet de configuration pour res.sendFile(). Exemples:

// assuming index.html is in the same directory as this script

res.sendFile(__dirname + '/index.html');

ou spécifiez une racine (qui est utilisée comme chemin de base pour le premier argument pour res.sendFile():

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

La spécification du rootchemin est plus utile lorsque vous transmettez un chemin de fichier généré par l'utilisateur qui pourrait potentiellement contenir des parties malformées / malveillantes comme ..(par exemple ../../../../../../etc/passwd). La définition du rootchemin empêche l'utilisation de tels chemins malveillants pour accéder aux fichiers en dehors de ce chemin de base.


1
Quelle est la meilleure façon de spécifier la racine comme étant un répertoire?
SuperUberDuper

1
@SuperUberDuper Vous voulez dire comme path.resolve(__dirname, '.../public')? Cela résoudra le sous-répertoire «public» du répertoire parent du script.
mscdex

cool! est-ce que cela stocke définitivement cette valeur dans __dirname à l'avenir?
SuperUberDuper

1
Salut, j'ai essayé le res.sendFile suivant (path.resolve (__ dirname + '/index.html', '../')) mais j'ai obtenu le message: Cannot GET /
SuperUberDuper

2
@SuperUberDuper <- ce gars avait raison (du moins pour moi). Il utilise la fonction de résolution qui normalise les chemins vous permettant de naviguer avec la ../../<etc>syntaxe de type. Notez la virgule entre __dirnameet ../public. L'utilisation du signe + ne fonctionne pas.
Helzgate

20

Essayez d'ajouter le chemin racine.

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

12

dans les fichiers .mjs, nous n'avons pour l'instant pas __dirname

Par conséquent

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

C'est une bonne solution qui a fonctionné pour moi car mon exigence était de revenir en arrière après avoir obtenu le chemin via __dirname. J'ai donc donné res.sendFile ('index.html', {root: './public/views'});
nilakantha singh deo

pour SITEMAP.XML dans les handelbars, c'est la bonne solution. Merci beaucoup
titoih

3

Si vous faites confiance au chemin, path.resolve est une option:

var path = require('path');

// All other routes should redirect to the index.html
  app.route('/*')
    .get(function(req, res) {
      res.sendFile(path.resolve(app.get('appPath') + '/index.html'));
    });

3

L'erreur est assez simple. La raison est probablement que votre fichier index.html ne se trouve pas dans le répertoire racine.

Ou s'il se trouve dans le répertoire racine, le référencement relatif ne fonctionne pas.

Vous devez donc indiquer l'emplacement exact de votre fichier sur le serveur. Cela pourrait être fait en utilisant la méthode dirname dans NodeJs. Remplacez simplement votre code par celui-ci:

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

Assurez-vous que vous ajoutez la barre oblique "/" symbole avant votre page d'accueil. Sinon, votre chemin deviendra: rootDirectoryindex.html

Alors que vous voulez que ce soit: rootDirectory / index.html


1

Je résous cela en utilisant la variable de chemin. L'exemple de code ressemblera à ci-dessous.

var path = require("path");

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname + '/index.html'));
})

0

Si vous travaillez sur le répertoire racine, vous pouvez utiliser cette approche

res.sendFile(__dirname + '/FOLDER_IN_ROOT_DIRECTORY/index.html');

mais si vous utilisez des routes qui se trouvent dans un dossier, disons, /Routes/someRoute.jsvous devrez faire quelque chose comme ça

const path = require("path");
...
route.get("/some_route", (req, res) => {
   res.sendFile(path.resolve('FOLDER_IN_ROOT_DIRECTORY/index.html')
});

0

Dans TypeScript avec chemin d'accès relatif à l'icône:

import path from 'path';

route.get('/favicon.ico', (_req, res) => res.sendFile(path.join(__dirname, '../static/myicon.png')));

0

Il redirigera vers index.html sur localhost: appel 8080.

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

0

J'ai utilisé le code ci-dessous et essayé d'afficher le fichier sitemap.xml

router.get('/sitemap.xml', function (req, res) {
    res.sendFile('sitemap.xml', { root: '.' });
});

-1

Cela peut être résolu d'une autre manière:

app.get("/", function(req, res){

    res.send(`${process.env.PWD}/index.html`)

});

process.env.PWD ajoutera le répertoire de travail au début du processus.


-2

Je l'ai fait et maintenant mon application fonctionne correctement,

res.sendFile('your drive://your_subfolders//file.html');

C'est une mauvaise pratique de coder en dur l'emplacement du fichier. Si vous déployez l'application sur une machine différente, le chemin du fichier sera probablement différent
Merve Sahin

-3

Vous pouvez envisager d'utiliser des doubles barres obliques sur votre répertoire, par exemple

app.get('/',(req,res)=>{
    res.sendFile('C:\\Users\\DOREEN\\Desktop\\Fitness Finder' + '/index.html')
})

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.