0

Using the javascript below, I am able to download files without any issues on my browser, but an issue I'm having is that I need the files to be renamed after download.

This is what the function that downloads the files looks like:

window.downloadFile = function (sUrl) {

    //iOS devices do not support downloading. We have to inform user about this.
    if (/(iP)/g.test(navigator.userAgent)) {
        alert('Your device do not support files downloading. Please try again in desktop browser.');
        return false;
    }

    //If in Chrome or Safari - download via virtual link click
    if (window.downloadFile.isChrome || window.downloadFile.isSafari) {
        //Creating new link node.
        var link = document.createElement('a');
        link.href = sUrl;

        if (link.download !== undefined) {
            //Set HTML5 download attribute. This will prevent file from opening if supported.
            var fileName = sUrl.substring(sUrl.lastIndexOf('/') + 1, sUrl.length);
            link.download = fileName;
        }

        //Dispatching click event.
        if (document.createEvent) {
            var e = document.createEvent('MouseEvents');
            e.initEvent('click', true, true);
            link.dispatchEvent(e);
            return true;
        }
    }

    // Force file download (whether supported by server).
    var query = '?download';

    window.open(sUrl + query, '_self');
}

window.downloadFile.isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
window.downloadFile.isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;

From my understanding, the code creates an anchor link and clicks on it to download the file. After doing some research, I found that the download attribute can change the file name, but when I try to this with the code it does not work. Right after link.href = sUrl; I added link.download = random()+".png"; and the following function as well:

function random() {
    var length = 32,
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
        retVal = "";
    for (var i = 0, n = charset.length; i < length; ++i) {
        retVal += charset.charAt(Math.floor(Math.random() * n));
    }
    return retVal;
}

Despite that change, it won't rename the files. What am I doing wrong?

Matt
  • 1,087
  • 1
  • 12
  • 28

1 Answers1

0

You've got a lot of unnecessary code here.

You've declared downloadFile as a function. You can't then just add isChrome and isSafari properties to it with the syntax you are using. You'd have to declare them within downLoadFile as properties (with this.isSafari = ... and this.isChrome = ...). But, really you don't need properties, just variables.

Also, you aren't actually calling downloadFile from anywhere.

Next, creating new properties on the window object and relying on navigator.userAgent are anti-patterns. That's exactly what we don't want to do.

You also don't need to check for link.download. Just set it. If the browser supports it, it will use it. If not, it won't. It won't throw an error if it's not supported.

And, you only need to use link.click() instead of creating and dispatching an event.

See the comments inline for more:

// If you are going to add properties to window, at least set them up in a 
// namespace that you are 100% sure doesn't already exist.
window.CustomNamespace = {};

window.CustomNamespace.downloadFile = function (sUrl) {

    // Create new link node.
    var link = document.createElement('a');
    link.href = sUrl;

    // Browser detection is a futile effort because navigator.userAgent will often
    // return inaccurate information and can be spoofed easily, creating security
    // holes in your application. Additionally, testing for all the different clients
    // and platforms is a never ending task. Use feature detection.
    
    // All you really care about is whether the client supports the feature.
    // You don't need to know what kind of client it is.
    if (link.download) {
      // download is supported. Just use it. Do you really care what browser it is?
      link.download = random() + ".png";
      
      console.log(link.download);
      
      link.click();  // Trigger the click event - no need to create/dispatch a new event.
    } else {
        alert('Your device do not support files downloading. Please try again in desktop browser.');
    }
}

function random() {
    var length = 32,
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
        retVal = "";
    for (var i = 0, n = charset.length; i < length; ++i) {
        retVal += charset.charAt(Math.floor(Math.random() * n));
    }
    return retVal;
}

// Invoke the function
window.CustomNamespace.downloadFile("test");
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71