Small JS script to download files on Safari
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I need a small JS piece of code to be able to download files (CSV, XML, Zip etc) to desktop from Safari. Currently I have some code which uses zip.js which works fine in Firefox when downloading files but for some reason this doesn’t work in Safari.

So I need a small piece of JS code that can be plugged into my existing code and can download files to desktop via Safari.


Why do you need JS for this? What's wrong with a simple download link on the page?
henrebotha 5 years ago
I'm dynamically generating content on the frontend using JS and I need users to be able to download this data. This is just a purely static HTML page with no server so I can't use ajax to send data to a server and creating a download link.
user0809 5 years ago
Could you be more precise on your need ? Where does the files come from ? a webserver ? a directory on your computer ? The best would be to have a demo page of your code working on firefox so we can adapt it to Safari
kerncy 5 years ago
The files are dynamically created in the user's browser and do not come from anywhere. Here is a link to the very last bit of my current script, the part of the script which actually performs the file zipping and saving using FileSaver.js
user0809 5 years ago

Crowdsource coding tasks.

3 Solutions

Example markup

<a id="link" href="#0">No download yet</a>

Vanilla JavaScript


link = document.getElementById("link");
link.href = "data:application/octet-stream," + encodeURIComponent(final_output_array); = "example-file.csv"; = "_blank";
link.textContent = "Download example-file.csv";


    .attr("href", "data:application/octet-stream," + encodeURIComponent(final_output_array))
    .attr("download", "example-file.csv")
    .attr("target", "_blank")
    .text("Download example-file.csv");

You should be able to create a download link for any file type like this.

I noticed that Safari does not support the download attribute yet, so please also try this out, if you experience problems:

jQuery using Blob


blob = new Blob(final_output_array, { type: "application/octet-stream" });

    .attr("href", URL.createObjectURL(blob))
    .attr("download", "example-file.csv")
    .attr("target", "_blank")
    .text("Download example-file.csv");

You might need to change application/octet-stream to the correct MIME type of the file content, e.g. text/xml (or application/xml) for XML, application/zip for zip, text/csv (or application/csv) for CSV files.

Could you modify this so it's jQuery? Thanks!
user0809 5 years ago
Here you go. Try it out.
LayZee 5 years ago
I ran this and it did download a file from Safari but it's just called 'Unknown' and not 'example-file.csv' Can you try this on Safari here?
user0809 5 years ago
Also, for the 'encodeURIComponent' method, can I pass in anything? e.g. strings, arrays, objects etc and they will be properly converted for download. Just like FileSaver.js?
user0809 5 years ago
I just tried again the updated script, still 'Unknown' file name. I'm on Mac OS Sierra using Safari 10.0.1
user0809 5 years ago
Now I'm getting 'TypeError: plugin.IsCommandKeyUndetectEnable is not a function. (In 'plugin.IsCommandKeyUndetectEnable()', 'plugin.IsCommandKeyUndetectEnable' is undefined)' Can you test with the jsfiddle and see if it works? If it works for you can you please send me the jsfiddle link? Thanks!
user0809 5 years ago
First argument to new Blob(array, object) must be an array:
LayZee 5 years ago
Now this latest fiddle doesn't download anything when I run it... Does it work for you?
user0809 5 years ago
I tried this on Firefox and it works but I need it to work for Safari
user0809 5 years ago
I'm sorry, I neither have a Mac or Safari. I gave it a try. If you can't get FileSaver to work with blob, then I'm afraid that I can't help you.
LayZee 5 years ago

I don't have Safari too. can you try it yourself, please?

// bitcoin:1C5NZCMkjJTf8v7t41QwW9EeCjJcLEbf5s
function setupInlineDownload(linkElement, fileName, fileContent) {
    var blob = new Blob([unicodeStringToTypedArray(fileContent)],  // yep, an array in array
        {type: 'application/octet-binary'});

        .attr('download', fileName)  // not supported in Safari (upto version 10), sorry
        .attr('href', URL.createObjectURL(blob))

// string to uint array, thanks to AJ ONeal @coolaj86
// see
function unicodeStringToTypedArray(s) {
    var escstr = encodeURIComponent(s);
    var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    var ua = new Uint8Array(binstr.length);, function (ch, i) {
        ua[i] = ch.charCodeAt(0);
    return ua;


setupInlineDownload($('#myLink'), 'test.csv', 'I\'m,not,so,good,in,CSV');

Hey user856,

First I tried most solutions with javascript(if not all), and most of them don't work - the file is downloaded with unknown file name or opened in new tab in the Safari browser. So I don't think js will work for this. Also you have said that this is only a purely static html page with no server. Actually this is not correct, because you are using a web server which sends the html page to the user browser. So depending on what hosting you will put your application, your hosting may provide support for php, .net, nodejs etc.

For me the best way to do this is to use a little php file alongiside your html page.

Create a new file called "force-download.php" alongside your index.html. The contents of force-download.php are:

$mimeType = $_POST['mimeType'];
$fileName = $_POST['fileName'];
$fileContent = $_POST['fileContent'];

header('Content-type: ' . $mimeType);
header('content-Disposition: attachment; filename=' . $fileName);
header('Pragma: no-cache');
header('Expires: 0');

echo $fileContent;

For html you only need this:

<div id="download-file"></div>

And this is your javascript after the html:

    var final_output_array = 'some data in array format';
    var fileName = 'newFile.csv';
    var mimeType = 'text/csv';
    var serverURL = 'force-download.php';

    makeDownloadLink(fileName, final_output_array, mimeType, serverURL);

    function makeDownloadLink(fileName, fileContent, mimeType, serverURL) {
        var form = $('<form id="downloadForm" action="'+serverURL+'" method="POST" target="_blank"></form>');

        form.append('<input type="hidden" name="fileName" value="'+fileName+'">');
        form.append('<input type="hidden" name="fileContent" value="'+fileContent+'">');
        form.append('<input type="hidden" name="mimeType" value="'+mimeType+'">');

        form.append('<input type="submit" value="Download File">');

Will you choose a solution?
dimitar almost 5 years ago
View Timeline