简体   繁体   中英

Button to download a document implemented with Express.js and node.js isn't working properly

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

在此处输入图片说明

Project Structure:

在此处输入图片说明

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

<!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

    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:

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

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/download

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.

Thank you!

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>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM