node.js TypeError: la ruta debe ser absoluta o especificar root para res.sendFile [no se pudo analizar JSON]

152

[add] Entonces mi próximo problema es que cuando intento agregar una nueva dependencia (npm install --save socket.io). El archivo JSON también es válido. Me sale este error: no se pudo analizar 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 

Así que he estado tratando de descubrir por qué este error ha regresado. Todos los archivos (HTML, JSON, JS) están dentro de la misma carpeta en mi escritorio. Estoy usando node.js y socket.io

Este es mi archivo 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');
});

Esto es lo que se devuelve:

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)
IE8IsBetterThenGoogleChrome
fuente

Respuestas:

331

El error es bastante claro, debe especificar una ruta absoluta (en lugar de relativa) y / o establecer rooten el objeto de configuración para res.sendFile(). Ejemplos:

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

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

o especifique una raíz (que se usa como la ruta base para el primer argumento para res.sendFile():

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

Especificar la rootruta es más útil cuando pasa una ruta de archivo generada por el usuario que podría contener partes malformadas / maliciosas como ..(por ejemplo ../../../../../../etc/passwd). Establecer la rootruta evita que dichas rutas maliciosas se utilicen para acceder a archivos fuera de esa ruta base.

mscdex
fuente
1
¿Cuál es la mejor manera de especificar la raíz como un directorio?
SuperUberDuper
1
@SuperUberDuper ¿Quieres decir como path.resolve(__dirname, '.../public')? Eso se resolverá en el subdirectorio 'público' del directorio principal del script.
mscdex
¡frio! ¿Esto almacena permanentemente este valor en __dirname en el futuro?
SuperUberDuper
1
Hola, probé lo siguiente res.sendFile (path.resolve (__ dirname + '/index.html', '../')) pero
recibí
2
@SuperUberDuper <- este tipo tenía razón (al menos para mí). Está utilizando la función de resolución que normaliza las rutas que le permiten navegar con ../../<etc>sintaxis de tipo. Observe la coma entre __dirnamey ../public. Usar un signo + no funciona.
Helzgate el
20

Intenta agregar la ruta raíz.

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

en archivos .mjs, por ahora no tenemos __dirname

por lo tanto

res.sendFile('index.html', { root: '.' })
Elias Goss
fuente
Esta es una buena solución que funcionó para mí, ya que mi requisito era volver después de obtener la ruta a través de __dirname. Entonces le di res.sendFile ('index.html', {root: './public/views'});
nilakantha singh deo
para SITEMAP.XML en handelbars, esta es la solución correcta. Muchas gracias
titoih
3

Si confía en la ruta, path.resolve es una opción:

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'));
    });
Michael Cole
fuente
3

El error es bastante sencillo. Lo más probable es que la razón sea que su archivo index.html no está en el directorio raíz.

O si está en el directorio raíz, entonces la referencia relativa no funciona.

Por lo tanto, debe indicarle al servidor la ubicación exacta de su archivo. Esto podría hacerse utilizando el método de nombre de directorio en NodeJs. Simplemente reemplace su código con este:

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

Asegúrese de agregar el símbolo de barra diagonal "/" antes de su página de inicio. De lo contrario, su ruta será: rootDirectoryindex.html

Mientras que desea que sea: rootDirectory / index.html

saadi123
fuente
1

Resuelvo esto usando la variable de ruta. El código de muestra se verá a continuación.

var path = require("path");

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

Si está trabajando en el directorio raíz, puede usar este enfoque

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

pero si está utilizando Rutas que están dentro de una carpeta, digamos /Routes/someRoute.jsque deberá hacer algo como esto

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

En mecanografiado con ruta relativa al icono:

import path from 'path';

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

Redirigirá a index.html en localhost: llamada 8080.

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

Utilicé el siguiente código e intenté mostrar el archivo sitemap.xml

router.get('/sitemap.xml', function (req, res) {
    res.sendFile('sitemap.xml', { root: '.' });
});
Hasan Batuhan Kurt
fuente
-1

Esto se puede resolver de otra manera:

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

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

});

process.env.PWD antepondrá el directorio de trabajo cuando se inició el proceso.

Abhishek Saharn
fuente
-2

Hice esto y ahora mi aplicación funciona correctamente,

res.sendFile('your drive://your_subfolders//file.html');
usuario10310158
fuente
Es una mala práctica codificar la ubicación del archivo. Si implementa la aplicación en una máquina diferente, la ruta del archivo probablemente será diferente
Merve Sahin
-3

Puede considerar usar barras dobles en su directorio, por ejemplo

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

Richard Mbingi
fuente