John Doe
John Doe

Reputation: 67

Ajax file downloads with same name

This is my Fiddle: https://jsfiddle.net/e6b5hdow/2/

const links = document.querySelectorAll('[href$=".jpg"], [href$=".png"], [href$=".mp4"], [href$=".avi"], [href$=".jpeg"], [href$=".mkv"], [href$=".csv"]');
links.forEach(link => link.classList.add('download-button'));


$('.name').prepend($("<div class='download-ui-container'><div class='start-download'>Starting Download..</div><div class='download-progress-container'><div class='download-progress'></div></div><a class='save-file'>Save File</a></div>"));


var _OBJECT_URL;

$(document).on('click', '.download-button', function(event) {
  var request = new XMLHttpRequest();
  fileDownload = $(this).attr('href');
  var _t = $(this);
  request.addEventListener('readystatechange', function(e) {
    if (request.readyState == 2 && request.status == 200) {
      _t.parents('td').find('.start-download').css('display', 'block');
      _t.parents('td').find('.download-button').hide();
    } else if (request.readyState == 3) {
      _t.parents('td').find('.download-progress-container').css('display', 'block');
      _t.parents('td').find('.start-download').hide()
    } else if (request.readyState == 4) {
      _OBJECT_URL = URL.createObjectURL(request.response);

      var fileName = fileDownload.split("/")
      fileName = fileName[fileName.length - 1]

      var downloadLink = document.createElement('a');
      console.log(downloadLink);
      downloadLink.href = _OBJECT_URL;
      downloadLink.download = fileName;

      // document.body.appendChild(downloadLink);
      downloadLink.click();
      _t.parents('td').find('.download-button').css('display', 'block');
      _t.parents('td').find('.download-progress-container').hide();
      _t.parents('td').find('.save-file').click();
      setTimeout(function() {
        window.URL.revokeObjectURL(_OBJECT_URL);

        _t.parents('td').find('.download-button').css('display', 'block');
        _t.parents('td').find('.save-file').css('display', 'hide');
      }, 60 * 1000);
    }
  });
  request.addEventListener('progress', function(e) {
    var percent_complete = (e.loaded / e.total) * 100;
    _t.parents('td').find('.download-progress').css('width', percent_complete + '%');
  });
  request.responseType = 'blob';
  request.open('get', fileDownload);
  request.send();
  return false;
});
.demo-container {
  width: 400px;
  margin: 60px auto;
}

.download-button {
  background-color: white;
  color: #2980b9;
  border: 2px solid #2980b9;
  font-family: inherit;
  outline: none;
  min-width: 100px;
  padding: 10px;
  font-size: inherit;
  border-radius: 2px;
  cursor: pointer;
  display: block;
  margin: 0 auto;
}

.start-download {
  text-align: center;
  display: none;
}

.download-progress-container {
  border: 1px solid #cccccc;
  padding: 4px;
  display: none;
  height: 20px;
}

.download-progress {
  background-color: #2980b9;
  display: inline-block;
  height: 100%;
}

.save-file {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


<table>
  <tr>
    <td class="name">
      <a href="https://upload.wikimedia.org/wikipedia/commons/9/9b/Sternwarte_Darmstadt_HDR_Panorama_10MB_-_Photographed_by_James_Breitenstein.jpg">First link, large file</a>
    </td>
  </tr>
  <tr>
    <br><br><br>
    <td class="name">
      <a href="https://images.pexels.com/photos/414612/pexels-photo-414612.jpeg">Second link small file</a>
    </td>
  </tr>
</table>

Here, I am trying to download the file using Ajax and show progress bar. It works perfectly but one problem.

If the first link file is big, and second link file is small.

Then if someone clicks on the first link and file starts downloading and

then immediately clicks on second link and file downloads because of small size, and first link file is still downloading.

After the first link click file is downloaded, it saves with the file with name of second file.

Reproducing steps:

Click on first link Click on second link If second link file downloads first, then the name of first link file is same as of second file link

I think, when I call the function again, the filename variable, it gets overwritten something.

Is it possible to use request header instead of filename?

enter image description here

Basically, what I need is.

A way to prevent the overwrite of variable name, when a function is called two times with different parameters, and the function called first time, takes longer to execute, and function called second time, executes within 1 sec.

Upvotes: 1

Views: 81

Answers (1)

localhost
localhost

Reputation: 513

just replace

fileDownload = $(this).attr('href');

with

var fileDownload = $(this).attr('href');

so that your variable is not considered global by javascript

Upvotes: 1

Related Questions