Javascript 使用 Express 从 NodeJS 服务器下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7288814/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:38:43  来源:igfitidea点击:

Download a file from NodeJS Server using Express

javascriptnode.jsfileexpressdownload

提问by Thiago Miranda de Oliveira

How can I download a file that is in my server to my machine accessing a page in a nodeJS server?

如何将服务器中的文件下载到访问 nodeJS 服务器中的页面的机器上?

I'm using the ExpressJS and I've been trying this:

我正在使用 ExpressJS,我一直在尝试这个:

app.get('/download', function(req, res){

  var file = fs.readFileSync(__dirname + '/upload-folder/dramaticpenguin.MOV', 'binary');

  res.setHeader('Content-Length', file.length);
  res.write(file, 'binary');
  res.end();
});

But I can't get the file name and the file type ( or extension ). Can anyone help me with that?

但我无法获取文件名和文件类型(或扩展名)。任何人都可以帮助我吗?

回答by loganfsmyth

Update

更新

Express has a helperfor this to make life easier.

Express有一个帮手,可以让生活更轻松。

app.get('/download', function(req, res){
  const file = `${__dirname}/upload-folder/dramaticpenguin.MOV`;
  res.download(file); // Set disposition and send it.
});

Old Answer

旧答案

As far as your browser is concerned, the file's name is just 'download', so you need to give it more info by using another HTTP header.

就您的浏览器而言,该文件的名称只是“下载”,因此您需要使用另一个 HTTP 标头为其提供更多信息。

res.setHeader('Content-disposition', 'attachment; filename=dramaticpenguin.MOV');

You may also want to send a mime-type such as this:

您可能还想发送这样的 mime 类型:

res.setHeader('Content-type', 'video/quicktime');

If you want something more in-depth, here ya go.

如果你想要更深入的东西,那就去吧。

var path = require('path');
var mime = require('mime');
var fs = require('fs');

app.get('/download', function(req, res){

  var file = __dirname + '/upload-folder/dramaticpenguin.MOV';

  var filename = path.basename(file);
  var mimetype = mime.lookup(file);

  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);

  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
});

You can set the header value to whatever you like. In this case, I am using a mime-type library - node-mime, to check what the mime-type of the file is.

您可以将标题值设置为您喜欢的任何值。在这种情况下,我使用 mime 类型库 - node-mime来检查文件的 mime 类型是什么。

Another important thing to note here is that I have changed your code to use a readStream. This is a much better way to do things because using any method with 'Sync' in the name is frowned upon because node is meant to be asynchronous.

这里要注意的另一件重要事情是我已将您的代码更改为使用 readStream。这是一种更好的处理方式,因为使用名称中带有 'Sync' 的任何方法都是不受欢迎的,因为 node 是异步的。

回答by Jossef Harush

Use res.download()

res.download()

It transfers the file at path as an “attachment”. For instance:

它将路径中的文件作为“附件”传输。例如:

var express = require('express');
var router = express.Router();

// ...

router.get('/:id/download', function (req, res, next) {
    var filePath = "/my/file/path/..."; // Or format the path using the `id` rest param
    var fileName = "report.pdf"; // The default name the browser will use

    res.download(filePath, fileName);    
});

回答by jordanb

For static files like pdfs, Word docs, etc. just use Express's static function in your config:

对于 pdf、Word 文档等静态文件,只需在配置中使用 Express 的静态功能:

// Express config
var app = express().configure(function () {
    this.use('/public', express.static('public')); // <-- This right here
});

And then just put all your files inside that 'public' folder, for example:

然后将所有文件放在该“公共”文件夹中,例如:

/public/docs/my_word_doc.docx

And then a regular old link will allow the user to download it:

然后一个常规的旧链接将允许用户下载它:

<a href="public/docs/my_word_doc.docx">My Word Doc</a>

回答by Benoit Blanchon

In Express 4.x, there is an attachment()method to Response:

在 Express 4.x 中,有一种attachment()方法可以Response

res.attachment();
// Content-Disposition: attachment

res.attachment('path/to/logo.png');
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png

回答by KARTHIKEYAN.A

'use strict';

var express = require('express');
var fs = require('fs');
var compress = require('compression');
var bodyParser = require('body-parser');

var app = express();
app.set('port', 9999);
app.use(bodyParser.json({ limit: '1mb' }));
app.use(compress());

app.use(function (req, res, next) {
    req.setTimeout(3600000)
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept,' + Object.keys(req.headers).join());

    if (req.method === 'OPTIONS') {
        res.write(':)');
        res.end();
    } else next();
});

function readApp(req,res) {
  var file = req.originalUrl == "/read-android" ? "Android.apk" : "Ios.ipa",
      filePath = "/home/sony/Documents/docs/";
  fs.exists(filePath, function(exists){
      if (exists) {     
        res.writeHead(200, {
          "Content-Type": "application/octet-stream",
          "Content-Disposition" : "attachment; filename=" + file});
        fs.createReadStream(filePath + file).pipe(res);
      } else {
        res.writeHead(400, {"Content-Type": "text/plain"});
        res.end("ERROR File does NOT Exists.ipa");
      }
    });  
}

app.get('/read-android', function(req, res) {
    var u = {"originalUrl":req.originalUrl};
    readApp(u,res) 
});

app.get('/read-ios', function(req, res) {
    var u = {"originalUrl":req.originalUrl};
    readApp(u,res) 
});

var server = app.listen(app.get('port'), function() {
    console.log('Express server listening on port ' + server.address().port);
});

回答by Vedran

Here's how I do it:

这是我的方法:

  1. create file
  2. send file to client
  3. remove file
  1. 创建文件
  2. 发送文件给客户端
  3. 删除文件

Code:

代码:

let fs = require('fs');
let path = require('path');

let myController = (req, res) => {
  let filename = 'myFile.ext';
  let absPath = path.join(__dirname, '/my_files/', filename);
  let relPath = path.join('./my_files', filename); // path relative to server root

  fs.writeFile(relPath, 'File content', (err) => {
    if (err) {
      console.log(err);
    }
    res.download(absPath, (err) => {
      if (err) {
        console.log(err);
      }
      fs.unlink(relPath, (err) => {
        if (err) {
          console.log(err);
        }
        console.log('FILE [' + filename + '] REMOVED!');
      });
    });
  });
};