用于下载使用Express.js和node.js实现的文档的按钮无法正常工作

问题描述:

在我的项目中,我希望用户单击按钮时能够下载文档.

In my project, I want the user to be able to download a document when he clicks on a button.

项目结构:

public/client.js

public/client.js

console.log('Client-side code running');

const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
  console.log('button was clicked');

  fetch('/clicked', {method: 'POST'})
    .then(function(response) {
      if(response.ok) {
        console.log('Click was recorded');
        return;
      }
      throw new Error('Request failed.');
    })
    .catch(function(error) {
      console.log(error);
    });
});

public/index.html

public/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Report Generation</title>
  </head>
  <body>
    <h1>Download your document!</h1>
    <button id="myButton">Click me!</button>
  </body>
  <script src="client.js"></script>
</html>

server.js

server.js

    console.log('Server-side code running');

    const express = require('express');
    const createDocumentService = 

    const app = express();

    // serve files from the public directory
    app.use(express.static('public'));

    // start the express web server listening on 8080
    app.listen(8081, () => {
      console.log('listening on 8080');
    });

    // serve the homepage
    app.get('/', (req, res) => {
      res.sendFile(__dirname + '/index.html');
    });
 app.get('/download', function(req, res){
         setTimeout(() => {
          res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {

              console.log(err);

          });
      }, 500)
      });


    app.post('/clicked', (req, res) => {
      const click = {clickTime: new Date()};
      console.log(click);

      setTimeout(() => {
          res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {

              console.log(err);

          });
      }, 500)
    });

运行该应用程序并单击按钮后:

After running the app and clicking the button:

当用户单击按钮时,由于以下原因,他应该会看到正在下载的报告文件:

When the user clicks on the button, he should see the report file being downloaded thanks to:

在client.js中

In client.js

button.addEventListener('click', function(e) {
  console.log('button was clicked');

  fetch('/clicked', {method: 'POST'})
    .then(function(response) {
      if(response.ok) {
        console.log('Click was recorded');
        return;
      }
      throw new Error('Request failed.');
    })
    .catch(function(error) {
      console.log(error);
    });
});

在service.js中:

In service.js:

app.post('/clicked', (req, res) => {
      const click = {clickTime: new Date()};
      console.log(click);

      setTimeout(() => {
          res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {

              console.log(err);

          });
      }, 500)
    });

但是,该文档未下载.
但是,当我连接到

But, the document doesn't get downloaded.
However, when I connect to

localhost:5353/下载

localhost:5353/download

我为下载文档编写的相同代码/逻辑写在按钮POST路由内,可以正常工作,并且确实下载了文档.
因此,我真的不明白为什么相同的代码对一个正常"路由有效,而对依赖于按钮的另一种路由无效.

The same code/logic I wrote for downloading the document and which is written inside the button POST route, works perfectly and the document does get downloaded.
So I don't really see why the same code is working for one "normal" route and isn't working for the other route that depends on the button.

谢谢!

您无法使用 ajax 下载文件,因为Javascript没有写权限.您可以只使用href链接,也可以使用 window.location 正常工作.

You cannot download file using ajax cause Javascript doesn't have right to write to file. You can just use a href link or use the window.location it will work fine.

HTML:

<a href="/download" class="button">Click me!</a>

使用 .button 类将链接的样式设置为按钮.

Use a .button class to style the link as a button.

JS:

button.addEventListener('click', function(e) {
  console.log('button was clicked');
  window.location="./download"
  // or window.open(url, '_blank') for new window.
});