res.sendFile ruta absoluta

137

Si hago un

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

entonces recibo una advertencia de consola del servidor

Expresar en desuso res.sendfile: utilizar en su res.sendFilelugar

pero funciona bien en el lado del cliente.

Pero cuando lo cambio a

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

Me sale un error

TypeError: la ruta debe ser absoluta o especificar raíz para res.sendFile

y index1.html no se presta

No puedo entender cuál es el camino absoluto. Tengo un publicdirectorio al mismo nivel que server.js. Estoy haciendo el res.sendFilede con server.js. También he declaradoapp.use(express.static(path.join(__dirname, 'public')));

Agregar mi estructura de directorio:

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

¿Cuál es la ruta absoluta que se especificará aquí?

Estoy usando Express 4.x.

Tostada Kaya
fuente
Si está utilizando el express.staticmiddleware para servir su directorio público, ¿por qué necesita res.sendFileenviarlo public/index1.html?
Mike S
1
Estoy llamando res.sendFiledesde dentro app.get('/', function(req, res){res.sendFile("...")})para enviarlo a pedido.
Kaya Toast

Respuestas:

311

El express.staticmiddleware está separado de res.sendFile, por lo que inicializarlo con una ruta absoluta a su publicdirectorio no hará nada res.sendFile. Necesita utilizar una ruta absoluta directamente con res.sendFile. Hay dos formas simples de hacerlo:

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

Nota: __dirname devuelve el directorio en el que se encuentra el script que se está ejecutando actualmente. En su caso, parece que server.jsestá en app/. Por lo tanto, llegar a public, tendrá que volver a cabo de una sola planta primera: ../public/index1.html.

Nota: pathes un módulo incorporado que necesita ser required para que el código anterior funcione:var path = require('path');

Mike S
fuente
14
res.sendFile('../public/index.html', {root: __dirname});también funciona y es más corto
Fabien Sa
Trabajando con ide express y webstorm: no obtuve ningún error, console.log(path.join(__dirname, '../public', 'index.html'));pero res.sendFile(path.join(__dirname, '../public', 'index.html'));solo trabajo con var path = require('path');
Quake1TF
¿No hay forma de predefinir la ruta absoluta para que pueda usarse en sendFile?
eran otzap
44
res.sendFile('../public/index.html', {root: __dirname});ya no funciona, ya que devuelve 403 Prohibido por ir por encima de la raíz. Hazlo en su res.sendFile('public/index.html', {root: path.dirname(__dirname)});lugar.
Trevor Robinson
48

Solo intenta esto en su lugar:

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

Esto funcionó para mí. la raíz: __ dirname tomará la dirección donde se encuentra server.js en el ejemplo anterior y luego para llegar al index1.html (en este caso) la ruta devuelta es llegar al directorio donde está la carpeta pública.

Kshitij Choudhary
fuente
¿Por qué esta opción no está documentada?
Timkay
9
res.sendFile( __dirname + "/public/" + "index1.html" );

donde __dirnameadministrará el nombre del directorio en el que server.jsreside el script que se está ejecutando actualmente ( ).

SOuřaan Gřg
fuente
Esta solución fue bastante sencilla. Gracias por la ayuda. Me pregunto por qué la gente recomienda usar el paquete 'ruta' para hacer lo mismo.
El tercer
3
@TheThird, supongo, el uso lo pathhace independiente del sistema operativo .
kmonsoor
7

Una alternativa que aún no se ha enumerado y que funcionó para mí es simplemente usar path.resolvecon cadenas separadas o solo una con toda la ruta:

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

O

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

(Nodo v6.10.0)

Idea obtenida de https://stackoverflow.com/a/14594282/6189078

Phil Gibbins
fuente
6

Basado en las otras respuestas, este es un ejemplo simple de cómo cumplir con el requisito más común:

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)

Esto también funciona como una forma simple de responder con index.html en cada solicitud , porque estoy usando una estrella *para capturar todos los archivos que no se encontraron en su directorio estático (público); que es el caso de uso más común para aplicaciones web. Cambie a /para devolver el índice solo en la ruta raíz.

Jaime Gómez
fuente
Agradable. Agradable y sucinto.
lharby
5

Intenté esto y funcionó.

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

process.cwd() Devuelve la ruta absoluta de su proyecto.

Luego :

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

Otra forma de hacerlo escribiendo menos código.

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

app.get('/', function(req, res) {
   res.sendFile('index.html');
});
Tim Anishere
fuente
55
Esto genera "TypeError: la ruta debe ser absoluta o especificar la raíz para res.sendFile"
GreenAsJade
1

¡puedes usar send en lugar de sendFile para que no te enfrentes con error! ¡Esto funciona te ayudará!

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

para decirle al navegador que su respuesta es un tipo de PDF

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

si desea que el archivo se abra inmediatamente en la misma página después de que el usuario lo descargue, escriba 'en línea' en lugar del archivo adjunto en el código anterior.

res.send(data)
Aref.T
fuente
0

Si desea configurar esto una vez y usarlo en todas partes, simplemente configure su propio middleware. Cuando configure su aplicación, utilice lo siguiente para definir una nueva función en el objeto de respuesta:

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

Luego úsalo de la siguiente manera:

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

Utilicé Node.Js y tuve el mismo problema ... resolví simplemente agregando un '/' al comienzo de cada script y enlace a un archivo estático css.

Antes de:

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

Después:

<link rel="stylesheet" href="/assets/css/bootstrap/bootstrap.min.css">
Jackson D
fuente
Tendría que configurar el servidor estático express para que esto funcione
Hum4n01d