3

I have a feeling security concerns may not allow this but is it possible to generate a file with JavaScript and allow the user to drag it to the desktop (or file system)?

The following code drags out a file from a server

files[0].addEventListener("dragstart",function(evt){
    evt.dataTransfer.setData("DownloadURL", "application/octet-stream:Eadui2.ttf:http://thecssninja.come/demo/gmail_dragout/Eadui.ttf");
},false);

And with the below code I can generate a file and have it download but I can't set the file name or let the user select the location.

var uriContent = "data:application/octet-stream," + encodeURIComponent(JSON.stringify(map));
location.href = uriContent;

Ideally I'd like a magical combination of both.

4
  • Why don't you try saving it to the server first, then downloading it, then deleting it from the server? Commented Jan 10, 2012 at 20:11
  • Have you tried files[0].addEventListener("dragstart",function(evt){ evt.dataTransfer.setData("DownloadURL", "application/octet-stream:Eadui2.ttf:data:application/octet-stream," + encodeURIComponent(JSON.stringify(map)); ); },false); ???
    – Ben
    Commented Jan 10, 2012 at 20:22
  • @Andrew Yes that's an option, my client wanted the app to have no server interaction but that might be the only way to do it.
    – kreek
    Commented Jan 10, 2012 at 20:24
  • See my answer, it should work. I'm sure there's a security issue with JavaScript generating then downloading content but it could be a workaround. Commented Jan 10, 2012 at 20:27

3 Answers 3

3

following code is currently working in Chrome only:

// generate downloadable URL, file name here will not affect stored file
var url = URL.createObjectURL(new File([JSON.stringify(map)], 'file_name.txt'));
// note that any draggable element may be used instead of files[0]
// since JSON.stringify returns a string, we use 'text' type in setData
files[0].addEventListener("dragstart", function(evt) {
  evt.dataTransfer.setData("DownloadURL", "text:file_name.txt:" + url);
}, false);

now, dragging our files[0] element from the browser to desktop or file system, will store there a text file called, file_name.txt.

Feel free to choose another file name :)

2

This is only possible for Chrome, and even in Chrome you can't set the location. If using only Chrome is okay then you will have the following options:

  1. Stick with Drag n' Drop like from the CSS Ninja's tutorial, then you should try Ben's answer. encodeURIComponent is one way, but if you have the file generated using BlobBuilder then you can use window.webkitURL.createObjectURL() to get the file's URL. You can also try using FileWriter() with requestFileSystem(TEMPORARY, ...).

  2. Chrome supports download attribute for anchor tags so you can have regular link for the user to click (dragging also works):

    <a href="#your_url" download="filename.ext">Download</a>

  3. For cross browser support I suggest Downloadify.

1

You could try sending it to the server, saving the file, checking the return value and firing the download file function, followed by a server file that deletes the file from the server.

Something like this (with jQuery)

$.ajax({
  url: 'saveFile.php',
  method: 'post',
  data: {
     Filedata: data// file data variable
  },
  success: function(d) {
    // save file function, where d is the filename
  }
})

PHP: $filename = ;//generate filename file_put_contents($filename, $_POST['Filedata']); echo $filename;

Obviously there is more to it but that should be the basics

Not the answer you're looking for? Browse other questions tagged or ask your own question.