0

A zip file is written in 'download_data' and there is no error or download response upon returning. 

Notes:

  • The printed data returned from the function appears to be zipfile data

  • I have not augmented or utilized download.stream or response.download and do not know whether it is necessary in this case

Please indicate what is missing in the following ajax call and/or controller function to spawn the zip file download.

jQuery.ajax({method:'get',url:'{{=URL('download_data')}}',
                data:fileIDs,
                success: function(){}

                });

# function in web2py controller
def download_data():
    import zipfile
    import cStringIO
    import contenttype as c
    vars = request.vars
    tempfile = cStringIO.StringIO()
    temparchive = zipfile.ZipFile(tempfile, 'w', zipfile.ZIP_DEFLATED)

    fileIDs = vars.values()
    try:
        for file_id in fileIDs:
            file = db.files[file_id].file
            fileLoc = db.files.file.retrieve_file_properties(file)['path'] + '/' + file
            temparchive.writestr(db.files[file_id].file_name, open(fileLoc, 'rb').read())

    finally:
        temparchive.close() #writes 
        response.headers['Content-Disposition'] = 'attachment;filename=files.zip'
        response.headers['Content-Type'] = 'application/zip'
        rtn = tempfile.getvalue()
        tempfile.close()
    return rtn
ballade4op52
  • 2,142
  • 5
  • 27
  • 42
  • Usually when you want the client to download something, you don't use ajax to retrieve it. Just send the user to a new tab with the url being the file to download. – Kevin B Sep 28 '15 at 19:15
  • It appears ajax is needed in this case to send the selected file id's and perform the controller logic to create the zipfile and retrieve each location of the file to read and place in the zip. – ballade4op52 Sep 28 '15 at 19:19
  • 1
    Not at all. All ajax is doing is generating a url, such as `http://domain.com?foo=bar&baz=helloworld&id=6` and then using it with XMLHttpRequest. You very easily could create that same url yourself using `'http://domain.com?' + $.param(data)` and set it as the src of a hidden iframe or a new tab. – Kevin B Sep 28 '15 at 19:20
  • In this case, the file data only exists on the server until there is an ajax request, so it would need to make the call anyway to retrieve the data. – ballade4op52 Sep 28 '15 at 19:24
  • I still don't understand why you feel the need to use ajax for this. Your ajax request is of type 'GET', which means it's no different than entering a url in your browser. it doesn't really matter what the server has to do behind the scenes, as long as it is responding with the file to download. (which it appears to be doing so in your case) – Kevin B Sep 28 '15 at 19:25
  • 1
    Look at it this way. It certainly is possible to take the data returned from the ajax request and open a download prompt. However, it's only going to work in a select few modern browsers, and is going to require some additional logic to make it work, whereas the alternative works in all browsers and doesn't even require an ajax request. – Kevin B Sep 28 '15 at 19:28

1 Answers1

0

Technically, a download can't be triggered by an ajax request. You have to either set window.location to the files' URL (in web2py this is the URL of the controller function that returns the file data), or rely on the 'currently dubious' download spec for html5.

For more details, see Download a file from Servlet using Ajax, and for the web2py origin of this question: https://groups.google.com/forum/#!topic/web2py/nJY9FSyNggo

Community
  • 1
  • 1
ballade4op52
  • 2,142
  • 5
  • 27
  • 42