node.js TypeError: il percorso deve essere assoluto o specificare root su res.sendFile [impossibile analizzare JSON]


152

[aggiungi] Quindi il mio prossimo problema è che quando provo ad aggiungere una nuova dipendenza (npm install --save socket.io). Anche il file JSON è valido. Ottengo questo errore: impossibile analizzare 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 

Quindi ho cercato di capire perché questo errore è tornato. Tutti i file (HTML, JSON, JS) si trovano nella stessa cartella sul mio desktop. Sto usando node.js e socket.io

Questo è il mio file 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');
});

Questo è ciò che viene restituito:

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)

Risposte:


331

L'errore è abbastanza chiaro, è necessario specificare un percorso assoluto (anziché relativo) e / o impostato rootnell'oggetto config per res.sendFile(). Esempi:

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

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

o specificare una radice (che viene utilizzata come percorso di base per il primo argomento per res.sendFile():

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

Specificare il rootpercorso è più utile quando si passa un percorso di file generato dall'utente che potrebbe potenzialmente contenere parti non valide / dannose come ..(ad esempio ../../../../../../etc/passwd). L'impostazione del rootpercorso impedisce l'utilizzo di tali percorsi dannosi per accedere ai file al di fuori di tale percorso di base.


1
qual è il modo migliore per specificare la radice come up a dir?
SuperUberDuper,

1
@SuperUberDuper Intendi come path.resolve(__dirname, '.../public')? Ciò si risolverà nella sottodirectory "pubblica" della directory principale dello script.
mscdex,

freddo! questo memorizzerà permanentemente questo valore in __dirname in futuro?
SuperUberDuper,

1
Ciao, ho provato il seguente res.sendFile (path.resolve (__ dirname + '/index.html', '../')) ma ricevo il messaggio: Impossibile ottenere /
SuperUberDuper

2
@SuperUberDuper <- questo ragazzo aveva ragione (almeno per me). Sta usando la funzione di risoluzione che normalizza i percorsi permettendoti di navigare con la ../../<etc>sintassi del tipo. Notare la virgola tra __dirnamee ../public. L'uso di un segno + non funziona.
Helzgate,

20

Prova ad aggiungere il percorso di root.

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

12

nei file .mjs per ora non abbiamo __dirname

quindi

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

Questa è una buona soluzione che ha funzionato per me poiché il mio requisito era tornare indietro dopo aver ottenuto il percorso attraverso __dirname. Quindi ho dato res.sendFile ('index.html', {root: './public/views'});
nilakantha singh deo,

per SITEMAP.XML nei handelbar, questa è la soluzione giusta. Grazie mille
fino

3

Se ti fidi del percorso, path.resolve è un'opzione:

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'errore è piuttosto semplice. Molto probabilmente il motivo è che il file index.html non si trova nella directory principale.

Oppure, se si trova nella directory principale, il riferimento relativo non funziona.

Quindi devi dire al server la posizione esatta del tuo file. Questo potrebbe essere fatto usando il metodo dirname in NodeJs. Sostituisci il tuo codice con questo:

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

Assicurati di aggiungere il simbolo "/" alla barra prima della tua home page. Altrimenti il ​​tuo percorso diventerà: rootDirectoryindex.html

Considerando che vuoi che sia: rootDirectory / index.html


1

Risolvo questo usando la variabile path. Il codice di esempio apparirà come di seguito.

var path = require("path");

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

0

Se stai lavorando su Root Directory, puoi usare questo approccio

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

ma se stai usando Percorsi all'interno di una cartella, diciamo /Routes/someRoute.jsche dovrai fare qualcosa del genere

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

0

In dattiloscritto con relativo percorso dell'icona:

import path from 'path';

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

0

Reindirizzerà a index.html su localhost: 8080 call.

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

0

Ho usato il codice qui sotto e ho provato a mostrare il file sitemap.xml

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

-1

Questo può essere risolto in un altro modo:

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

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

});

process.env.PWD anteporrà la directory di lavoro all'avvio del processo.


-2

L'ho fatto e ora la mia app funziona correttamente,

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

È una cattiva pratica hardcodificare la posizione del file. Se si distribuisce l'applicazione su un altro computer, il percorso del file sarà molto probabilmente diverso
Merve Sahin,

-3

Potresti considerare di usare doppie barre nella tua directory, ad es

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.