【问题标题】:How to make these links to download files when clicked in node.js?在node.js中单击时如何使这些链接下载文件?
【发布时间】:2015-11-13 19:11:36
【问题描述】:

我是 Node 新手,我真的被困住了。

我正在尝试让我的网络服务器在当前目录中查找文件并将它们作为链接显示在浏览器中,以便我可以下载它们。

但是,文件列表会随着每个请求而更新并一遍又一遍地显示。我不能使用任何框架或外部组件,我已经坚持了两天。我真的做了很多研究并尝试了很多东西,但仍然无法让它发挥作用。

我将在下面添加我最后一次尝试的代码,如果有人可以帮助我提供一点信息,我将不胜感激。谢谢!

 var http = require("http");
 var fs = require("fs");
 var currentServerDir = ".";
 var port = 8080;
 var content = "";
 var server = http.createServer(handlerRequest).listen(8080);

 function handlerRequest(request, response) {
     fs.readdir(currentServerDir, function getFiles(error, items) {
         items.forEach(function getItems(item) {
             content += "<br><a href= " + "\" " + item + "\" " + ">" + item + "</a><br>";
         });
     });
     response.writeHead(200, {
         'Content-Type': 'text/html'
     });
     response.write(content);
     response.end();
 }

编辑:

我关注了Node.js Generate html

并从那里借了一些代码。现在我可以点击一个文件,而不是下载或查看它只是说“未定义”。

    var http = require('http');
    var content
    function getFiles()
    {
    fs.readdir(currentServerDir, function getFiles(error, items)
    {
    items.forEach(function getItems(item)
    {
    content+= "<br><a href= " + "\" " + item + "\" " + ">" +item +        "</a><br>";
    });
    });
    }

    http.createServer(function (req, res) {
    var html = buildHtml(req);

    res.writeHead(200, {
   'Content-Type': 'text/html',
   'Content-Length': html.length,
   'Expires': new Date().toUTCString()
   });

       res.end(html);

   }).listen(8080);

   function buildHtml(req) {
   var header = '';
   var body = content;

    return '<!DOCTYPE html>'
    + '<html><header>' + header + '</header><body>' + body + '</body>    </html>';
    };

【问题讨论】:

  • 您没有为新请求清除“内容”变量。将“内容”变量移动到 handleRequest 范围。见gist.github.com/alexeysmorkalov/c8fb7e7be72ce90788da
  • 其实还是不行。它没有显示任何内容:/
  • 好的,我编辑了要点,请再次检查。由于 readdir 是异步的,您应该在它的回调中结束请求。这仅解决了列表问题。要使下载链接正常工作,您应该考虑您的服务器将如何处理“下载”请求。我想要一个像express这样的框架。或者,如果您想从本地文件系统下载,请使用“file://”协议格式化链接。
  • 好的,谢谢大佬!列表本身现在工作正常。除了下载。我在它前面加上了 file://,但下载仍然无法正常工作。但我正在路上,再次感谢!
  • 提示 - 您应该使用绝对路径,而不仅仅是 file:// 协议的文件名

标签: javascript node.js


【解决方案1】:

您的代码中存在一些问题。

  1. 你永远不会调用getFiles(),导致content永远不会被填充
  2. 如果你打电话给getFiles()content最后还是空的,因为你使用fs.readdir()。这是一个异步函数,在用于构建您的 html 页面之前无法填充 content
  3. 您以相同方式处理对服务器的每个请求,因此您将无法下载任何文件,因为您将始终只显示您的页面。

您可以使用作为对您的问题的评论发布的要点 AlexS 轻松修复前 2 个问题。第三个需要更多设置,但如果您使用 Express,则可以轻松设置。

【讨论】:

    【解决方案2】:

    您可以将download 标签添加到您的 HTML 链接:

    items.forEach(function getItems(item)
    {
       content+= "<br><a href= " + "\" " + item + "\" " + " download>" +item +        "</a><br>";
    });
    

    MDN reference

    【讨论】:

    • 我试过了;当我打开一些文件时,它们包含 var 内容的值,所以很多 标签而不是它们的原始内容。
    • 这可能是因为您的节点服务器有一个返回 'Content-Type': 'text/html' HTTP 响应的处理程序?
    【解决方案3】:

    如果您不关心浏览器支持,您可以使用a 标签中的下载属性。 它看起来像这样:

    <a href="test.html" download="nameOfFileAfterDL">DL me!</a>
    

    Firefox 14+ 和 Chrome 20+ 支持

    但是如果你想要一个通用的解决方案,你可以在发送文件之前压缩文件,据我所知,“点击它们”时总是会下载 .zip。

    您可以使用'node-ziparchiver 来压缩您的文件。

    【讨论】:

    • 下载属性不起作用,但使用“node-zip” - 这就像一个作业,我真的只能使用开箱即用的模块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 2013-04-27
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    相关资源
    最近更新 更多