Nodejs envía archivo en respuesta


113

El framework Expressjs tiene un método sendfile (). ¿Cómo puedo hacer eso sin usar un marco completo? Estoy usando node-native-zip para crear un archivo y quiero enviárselo al usuario.

Respuestas:


183

Aquí hay un programa de ejemplo que enviará myfile.mp3 transmitiéndolo desde el disco (es decir, no lee todo el archivo en la memoria antes de enviar el archivo). El servidor escucha en el puerto 2000.

[Actualización] Como lo mencionó @Aftershock en los comentarios, util.pumpse ha ido y fue reemplazado con un método en el prototipo de Stream llamado pipe; el código siguiente refleja esto.

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);

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


1
Pero no estoy transmitiendo un archivo desde el servidor, creo el archivo
— andrei

Por "flujo" me refiero a "enviar los datos del archivo a la conexión mientras se leen" en lugar de "leer todo el archivo en la memoria y luego enviar todos esos datos a la conexión de una vez" (que es el típico enfoque ingenuo). No me refiero a "transmitir los datos desde la memoria sin que vayan al disco". La publicación que vinculé explica con más detalle.
— Michelle Tilley

6
util.pump (readStream, respuesta); se deprecia ... use readStream.pipe (respuesta);
— Réplica


@Abdul No estoy seguro de entender su pregunta; ¿quieres enviarme un correo electrónico ?
— Michelle Tilley

13

Necesita usar Stream para enviar un archivo (archivo) en una respuesta; además, debe usar el tipo de contenido apropiado en el encabezado de su respuesta.

Hay una función de ejemplo que lo hace:

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");
      }
    });
  }
}

El propósito del campo Tipo de contenido es describir los datos contenidos en el cuerpo lo suficientemente completo como para que el agente de usuario receptor pueda elegir un agente o mecanismo apropiado para presentar los datos al usuario, o tratar los datos de una manera apropiada.

"application / octet-stream" se define como "datos binarios arbitrarios" en RFC 2046, el propósito de este tipo de contenido es guardarlo en el disco; es lo que realmente necesita.

"filename = [nombre del archivo]" especifica el nombre del archivo que se descargará.

Para obtener más información, consulte este tema de stackoverflow .


cómo la solicitud de llamada en el lado del cliente proporciona el código del lado del cliente
— ashwini

1
tenga en cuenta que la función 'existe' está obsoleta.
— Ievgen Naida
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.