1

我知道已经有几个关于这个的问题,但这些解决方案都没有奏效。

我试图单击一个 div,然后 jQueryget向我的控制器发出请求,最后下载静态文件 (Zip)。使用 chrome 开发工具,我看到请求以有效 200 的形式返回。请求的响应似乎是 chrome 的尝试渲染,但我可以找出 zip 文件中包含的文件的名称,所以我可以说它发现一切都是正确的。

响应头是:

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

我的控制器逻辑:

    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 
     }

我不确定为什么我的浏览器实际上没有下载该文件。我尝试了很多不同的控制器逻辑变体,但结果都一样。

我尝试过的一些事情:

  • 内容类型为 'application/octect-stream;'
  • response.outputStream << file.bytes
  • response.outputStream << file.newInputStream()
  • 我添加了内容长度
  • 在流写入后移动内容类型

我正在使用 Grails 2.0.4

4

2 回答 2

4

Gregg 的评论是正确的,但有一些解决方法,这就是我的工作方式:

获取jQuery AJAX 文件下载插件 (希望您使用的是 jquery ;))

我已经看到了替代方案,但没有尝试过

这基于动态构建表单并将其发布到控制器来执行 HTTP 请求(不是 Ajax),同时仍为您提供所需的 AJAX 体验。如果这看起来有点笨拙,它是,但它是我发现这个工作的唯一方法。上面的 URL 对潜在问题进行了讨论。在 jQuery 中调用插件,如:

$("#myDiv").click(function () {
   $.download('${createLink(controller: 'download', action: 'zipFile')}', 'fileName=' + $("#myTextBox").val()); 
});

您的控制器看起来很接近,使用您已经尝试过的应该可以工作:

response.setHeader("Content-Type", "application/zip") 
response.setHeader("Content-disposition", "attachment;filename=${file.name}")
response.outputStream << file.newInputStream()

我已经使用了一段时间了,没有任何问题(还)

于 2012-07-12T23:47:21.127 回答
1

在标头中设置内容处置时,值得牢记以下几点,因为 Chrome 对格式非常严格,如果您弄错了,您可能会收到“重复标头”错误: http: //www.intelligrape.com/博客/2012/04/11/duplicate-headers-received-from-server-fix-for-chrome/

于 2012-07-13T07:07:37.213 回答