caminho absoluto res.sendFile


137

Se eu fizer uma

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

então recebo um aviso do console do servidor

expresso obsoleto res.sendfile: use em res.sendFilevez disso

mas funciona bem no lado do cliente.

Mas quando eu mudo para

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

Eu recebo um erro

TypeError: o caminho deve ser absoluto ou especificar raiz para res.sendFile

e index1.htmlnão é renderizado.

Eu sou incapaz de descobrir qual é o caminho absoluto. Eu tenho publicdiretório no mesmo nível que server.js. Eu estou fazendo o res.sendFilede com server.js. Eu também declareiapp.use(express.static(path.join(__dirname, 'public')));

Adicionando minha estrutura de diretórios:

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

Qual é o caminho absoluto a ser especificado aqui?

Estou usando o Express 4.x.


Se você estiver usando o express.staticmiddleware para servir seu diretório público, por que você precisa res.sendFileenviar public/index1.html?
Mike S

1
Estou ligando res.sendFilede dentro app.get('/', function(req, res){res.sendFile("...")})para enviá-lo sob demanda.
Kaya Toast

Respostas:


311

O express.staticmiddleware é separado res.sendFile, portanto, inicializá-lo com um caminho absoluto para o publicdiretório não fará nada res.sendFile. Você precisa usar um caminho absoluto diretamente com res.sendFile. Existem duas maneiras simples de fazer isso:

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

Nota: __dirname retorna o diretório em que o script atualmente em execução está. No seu caso, parece que server.jsestá dentro app/. Então, para chegar public, você vai precisar voltar a um nível em primeiro lugar: ../public/index1.html.

Nota: pathé um módulo interno que precisa ser required para que o código acima funcione:var path = require('path');


14
res.sendFile('../public/index.html', {root: __dirname});também funciona e é menor
Fabien Sa

Trabalhando com expressa e WebStorm IDE: não tem erro no console.log(path.join(__dirname, '../public', 'index.html'));, mas res.sendFile(path.join(__dirname, '../public', 'index.html'));o trabalho apenas com var path = require('path');
Quake1TF

Não há como pré-definir o caminho absoluto para que ele possa ser usado no sendFile?
Eran otzap

4
res.sendFile('../public/index.html', {root: __dirname});não funciona (mais), pois retorna 403 Proibido devido a ir acima da raiz. Faça em res.sendFile('public/index.html', {root: path.dirname(__dirname)});vez disso.
Trevor Robinson

48

Apenas tente isso:

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

Isso funcionou para mim. a raiz: __ dirname pegará o endereço em que server.js está no exemplo acima e, em seguida, para chegar ao index1.html (nesse caso), o caminho retornado será o diretório onde está a pasta pública.


Por que essa opção não está documentada?
timkay 25/04

9
res.sendFile( __dirname + "/public/" + "index1.html" );

onde __dirnamegerenciará o nome do diretório em que o script atualmente em execução ( server.js) reside.


Esta solução foi bem simples. Obrigado pela ajuda. Gostaria de saber por que as pessoas recomendam usar o pacote 'path' para fazer o mesmo.
The Third

3
@TheThird eu acho, usando o pathtorna independente do sistema operacional.
kmonsoor 27/04/2016

7

Uma alternativa que ainda não foi listada e que funcionou para mim é simplesmente usar path.resolvecom strings separadas ou apenas uma com todo o caminho:

// 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ó v6.10.0)

Idéia originada de https://stackoverflow.com/a/14594282/6189078


6

Com base nas outras respostas, este é um exemplo simples de como cumprir o requisito mais comum:

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)

Isso também funciona como uma maneira simples de responder com index.html em todas as solicitações , porque estou usando uma estrela *para capturar todos os arquivos que não foram encontrados no diretório estático (público); qual é o caso de uso mais comum para aplicativos da web. Mude para /para retornar o índice apenas no caminho raiz.


Agradável. Agradável e sucinto.
lharby 31/01

5

Eu tentei isso e funcionou.

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

4

process.cwd() retorna o caminho absoluto do seu projeto.

Então :

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

3

Outra maneira de fazer isso escrevendo menos código.

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

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

5
Isso gera "TypeError: o caminho deve ser absoluto ou especificar a raiz para res.sendFile"
GreenAsJade 25/17/17

1

você pode usar send em vez de sendFile para não enfrentar erros! isso funciona irá ajudá-lo!

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

por informar ao navegador que sua resposta é do tipo PDF

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

se você deseja que o arquivo seja aberto imediatamente na mesma página após o usuário fazer o download. escreva 'inline' em vez do anexo no código acima.

res.send(data)

0

Se você deseja configurar isso uma vez e usá-lo em qualquer lugar, basta configurar seu próprio middleware. Ao configurar seu aplicativo, use o seguinte para definir uma nova função no objeto de resposta:

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

Em seguida, use-o da seguinte maneira:

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

0

Eu uso o Node.Js e tive o mesmo problema ... Resolvi adicionando um '/' no início de cada script e link para um arquivo estático css.

Antes:

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

Depois de:

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

Você teria que configurar o servidor estática expressa para que isso funcione
Hum4n01d
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.