I know there are a couple questions on SO already concerning this but none of those solutions worked.
I’m attempting to click a div, which in turn jQuery makes a get request to my contoller and finally downloads the static file (Zip). Using the chrome dev tools, I see the request going and coming back as a valid 200. The response of the request appears to be the chrome’s attempted render but I can make out the names of the files that are contained within the zip file so I can tell it’s finding everything correct.
The response headers are:
Content-Type:application/zip
Content-disposition:attachment;filename=myFile.zip
Date:Thu, 12 Jul 2012 20:18:05 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
My controller logic:
def root = request.getSession().getServletContext().getRealPath("/")
def file = new File("C:\path\to\my\file")
if (file.exists()) {
def os = response.outputStream
response.setHeader("Content-Type", "application/zip")
response.setHeader("Content-disposition", "attachment;filename=${file.name}")
def bytes = file.text.bytes
for(b in bytes) {
os.write(b)
}
os.flush()
org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes().renderView = false
}
I’m not sure why my browser is not actually downloading the file. I’ve tried so many different variants of the controller logic but all with the same result.
Some things I’ve tried:
- Content-Type as ‘application/octect-stream;’
response.outputStream << file.bytesresponse.outputStream << file.newInputStream()- I’ve added content-length
- Moving the content type after the stream writes
I’m using Grails 2.0.4
Gregg’s comment is correct, but there are workarounds, here is how I have this working:
Grab the jQuery AJAX file download plugin (hope you are using jquery 😉 )
I’ve seen an alternative but not tried it
This does a HTTP request (not Ajax) based on dynamically building a form and posting that to the controller while still giving you the AJAX experience you are after. If this seems a tad clunky, it is, but its the only way I’ve found this to work. The URL above has a dicussion on the potential issues.
In jQuery call the plugin like:
Your controller looks close, using what you have already tried should work:
I’ve been using this for a while now without any issues (yet)