views:

120

answers:

6

It seems like this question is asked periodically and the common response is "You shouldn't do that with AJAX anyway. Just set the window location to the file."

But I'm trying to request a file that doesn't actually exist out on the server anywhere. It's dynamically generated (by a Django view) given the GET/POST context parameters. The file I want to retrieve via AJAX, and then save to the client machine, is a text file (csv).

I can currently get the text to the client machine (and can verify this by seeing it in logging or an alert) but cannot then figure out how to save this text to a file inside of the AJAX success callback fn.

Essentially, is this possible, is it something JS can do? That is, to open file save dialogs for "files" that are actually AJAX response text?

A: 

This isn't something JavaScript (and therefore jQuery or anything other JS framework) is allowed to do, for security reasons. You may be able to do what you want to flash or another route, but not JavaScript. Bear in mind Flash has it's own slew of security restrictions for this as well.

(Yes, IE can do this via an ActiveX object, but I'm not counting that as a "solution" here)

Nick Craver
Thanks for not counting IE/ActiveX as a solution... I wouldn't either. It seems like this isn't really possible with JS and I want to steer clear of Flash, other MS or proprietary frameworks. So I'll probably just use JS to include, populate, and then submit a HTML form wholly behind the scenes.
Dave Masselink
A: 

Basically, no. Javascript cant save anything to the local machine due to security restrictions. Your best bet may be to have a signed applet that the user can trust to write the file, or put it in a textarea that they can then easily copy and paste into a new file.

jgubby
The text file is likely a huge (few MB) text file of raw data in a CSV file. The size is variable depending on user options... but still probably too big to cut and paste. I hadn't mentioned that before though... so for small files, this probably would be a fine solution.
Dave Masselink
A: 

Could you not use the PHP rename() function for this, instead of just Javascript? Call to a PHP file and pass the name of the file you want to copy along with where as parameters?

d2burke
No. PHP runs on the server, not in the browser.
Stephen P
Agreed, I assumed we were in agreement that JS could not accomplish the task, so I offered an alternative as others have done, but thanks for the tip anyway, though its something I already knew.
d2burke
I'm using Django (so Python) on the server side... so I'll have to see if there's a good way to do the same thing in python.
Dave Masselink
+1  A: 

From the browser's point of view, it doesn't matter if the file exists or not, it's just a resource on a server that it's requesting. I think you're going to need to do some version of "Just set the window location to the file". If you set the content type in the header to something that the browser doesn't recognize, I believe it will ask the user if they want to save it.

morgancodes
I think what I'm going to have to do is emulate a form submission through JS. I found a jQuery plugin that does this. It's not quite perfectly what I want, but I may base my solution on this: http://www.filamentgroup.com/lab/jquery_plugin_for_requesting_ajax_like_file_downloads/
Dave Masselink
+1  A: 

As others mentioned, you can't do it only with JavaScript.

IMO the best option would be the Flash 10+ FileReference API.

There are some good JavaScript wrapper libraries like Downloadify that provide a JavaScript API to access those methods.

Give a look to this demo.

CMS
I like your solution.
Andre Bossard
Thanks for the info CMS. I think your solution works well (thanks for providing a demo link), but I've made efforts elsewhere in this project to stay away from Flash. That was primarily for iPhone compatibility... but I guess iOS isn't going to be dealing with file downloads anyway. Hmm... I'll have to think more about this one.
Dave Masselink
A: 

I have the same problem. You can try this

<button id="Save">Save</button>
<img src="MakeThumbnail.ashx?Image=1.jpg" id="imgCrop">

$("#Save").click(function (e) {
    url = $("#imgCrop").attr("src")+"&Action=Save"
    e.preventDefault();  //stop the browser from following
    window.location.href = url;
});
evgeny