Nodejs enviam arquivo em resposta


113

O framework Expressjs tem um método sendfile (). Como posso fazer isso sem usar uma estrutura inteira. Estou usando o node-native-zip para criar um arquivo e quero enviá-lo ao usuário.

Respostas:


183

Aqui está um programa de exemplo que enviará meuarquivo.mp3 por streaming do disco (ou seja, ele não lê o arquivo inteiro na memória antes de enviar o arquivo). O servidor escuta na porta 2000.

[Update] Conforme mencionado por @Aftershock nos comentários, util.pumpdesapareceu e foi substituído por um método no protótipo do Stream chamado pipe; o código abaixo reflete isso.

var http = require('http'),
    fileSystem = require('fs'),
    path = require('path');

http.createServer(function(request, response) {
    var filePath = path.join(__dirname, 'myfile.mp3');
    var stat = fileSystem.statSync(filePath);

    response.writeHead(200, {
        'Content-Type': 'audio/mpeg',
        'Content-Length': stat.size
    });

    var readStream = fileSystem.createReadStream(filePath);
    // We replaced all the event handlers with a simple call to readStream.pipe()
    readStream.pipe(response);
})
.listen(2000);

Retirado de http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/


1
Mas não estou transmitindo um arquivo do servidor, crio o arquivo
— andrei

Por "fluxo", quero dizer "enviar os dados do arquivo para a conexão à medida que eles estão sendo lidos", em vez de "ler o arquivo inteiro na memória e enviar todos os dados para a conexão de uma vez" (que é a abordagem ingênua típica). Não quero dizer "transmitir os dados da memória sem ir para o disco". O post que eu vinculei explica com mais detalhes.
— Michelle Tilley

6
util.pump (readStream, resposta); está depreciado ... use readStream.pipe (resposta);
— Aftershock de


@Abdul Não tenho certeza se entendi sua pergunta; quer me enviar um e-mail ?
— Michelle Tilley

13

Você precisa usar o Stream para enviar o arquivo (archive) em uma resposta, além disso, você deve usar o tipo de conteúdo apropriado no cabeçalho da resposta.

Há uma função de exemplo que faz isso:

const fs = require('fs');

// Where fileName is name of the file and response is Node.js Reponse. 
responseFile = (fileName, response) => {
  const filePath =  "/path/to/archive.rar" // or any file format

  // Check if file specified by the filePath exists 
  fs.exists(filePath, function(exists){
      if (exists) {     
        // Content-type is very interesting part that guarantee that
        // Web browser will handle response in an appropriate manner.
        response.writeHead(200, {
          "Content-Type": "application/octet-stream",
          "Content-Disposition": "attachment; filename=" + fileName
        });
        fs.createReadStream(filePath).pipe(response);
      } else {
        response.writeHead(400, {"Content-Type": "text/plain"});
        response.end("ERROR File does not exist");
      }
    });
  }
}

O objetivo do campo Content-Type é descrever os dados contidos no corpo de forma completa o suficiente para que o agente do usuário receptor possa escolher um agente ou mecanismo apropriado para apresentar os dados ao usuário ou, de outra forma, lidar com os dados de maneira apropriada.

"application / octet-stream" é definido como "dados binários arbitrários" no RFC 2046, o objetivo deste tipo de conteúdo é ser salvo em disco - é o que você realmente precisa.

"filename = [nome do arquivo]" especifica o nome do arquivo que será baixado.

Para obter mais informações, consulte este tópico stackoverflow .


como a solicitação de chamada no lado do cliente fornece o código do lado do cliente
— ashwini,

1
observe que a função 'existe' está obsoleta.
— Ievgen Naida
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.