在rails中,无法覆盖content-disposition文件名

max*_*der 7 fastercsv content-disposition chromium http-headers ruby-on-rails-3

我使用的是Rails 3.1.0.rc8和Chromium 15.0.874.102.

我想设置CSV下载的文件名.我按照这样做方案,但发现自己无法修改filename的的Content-Disposition头.

这是我的代码:

module ActionController 
  module CSVHelper

    def render_csv options={}
      if request.env['HTTP_USER_AGENT'] =~ /msie/i
        headers['Pragma'] = "public"
        headers['Content-Type'] = "text/plain"
        headers['Cache-Control'] = "no-cache, must-revalidate, post-check=0, pre-check=0"
        headers['Expires'] = "0"
      else
        headers['Content-Type'] = "text/csv"
      end

      filename = generate_filename options.delete(:basename)
      headers['Content-Disposition'] = "attachment; filename=#{filename}"
    end

    def generate_filename basename=nil, suffix="csv"
      filename = basename || params[:action]
      filename << ".#{suffix}"
      filename
    end

  end
end    
Run Code Online (Sandbox Code Playgroud)

在我的控制器中:

respond_to do |format|
  format.html
  format.csv do
    render_csv(:basename => "my_filename")
    Rails.logger.debug "HEADERS: #{headers.to_s}"
  end
end  
Run Code Online (Sandbox Code Playgroud)

在我的日志中:

[2011-11-28 12:25:49.611] DEBUG - HEADERS: {"Content-Type"=>"text/csv", "Content-Disposition"=>"attachment; filename=my_filename.csv"}
Run Code Online (Sandbox Code Playgroud)

在Chromium网络检查器工具中,我在响应标头中看到以下内容:

Content-Type: text/plain
Content-Disposition: attachment; filename=index.csv
Run Code Online (Sandbox Code Playgroud)

如果我将其更改Content-Type为类似内容foo/bar,我会在网络检查器工具中看到更改.无论我设置什么filename,它仍然存在index.csv.

谢谢,马克斯

mae*_*ics 11

根据HTTP/1.1规范附录Content-Disposition部分,文件名必须是带引号的字符串:

   filename-parm = "filename" "=" quoted-string
   ...
Run Code Online (Sandbox Code Playgroud)

一个例子是

   Content-Disposition: attachment; filename="fname.ext"
Run Code Online (Sandbox Code Playgroud)

所以你可能需要进行以下更改(注意引号):

headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
Run Code Online (Sandbox Code Playgroud)