7

Tôi đang sử dụng Rails 3.1.0.rc8 và Chromium 15.0.874.102.trong đường ray, không thể ghi đè lên tên tệp nội dung bố trí

Tôi muốn đặt tên tệp của bản tải xuống CSV. Tôi đang theo dõi số SO solution này, nhưng thấy mình không thể sửa đổi số filename của tiêu đề Content-Disposition.

Đây là mã của tôi:

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  

Và trong bộ điều khiển của tôi:

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

Trong log của tôi:

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

Trong Chromium công cụ thanh tra mạng, tôi thấy sau đây trong Tiêu đề phản hồi của tôi:

Content-Type: text/plain 
Content-Disposition: attachment; filename=index.csv 

Nếu tôi thay đổi Content-Type thành một cái gì đó như foo/bar, tôi thấy sự thay đổi đến trong công cụ kiểm tra mạng của tôi. Bất kể tôi đặt số filename là gì, nó vẫn là index.csv.

Cảm ơn, Max

+0

bạn có thiết lập chính xác chế độ xem không? – baol

+0

chế độ xem hiển thị như mong đợi, nếu đó là ý của bạn; nội dung của tệp được tải xuống trông giống như tôi muốn – maxenglander

Trả lời

11

Theo Content-Disposition section of the appendices to the HTTP/1.1 specification tên tập tin phải là một chuỗi trích dẫn:

filename-parm = "filename" "=" quoted-string 
    ... 

Một ví dụ là

Content-Disposition: attachment; filename="fname.ext" 

Vì vậy, bạn có thể cần phải thực hiện thay đổi sau (lưu ý dấu ngoặc kép):

headers['Content-Disposition'] = "attachment; filename=\"#{filename}\"" 
+0

Lưu ý rằng nếu tên tệp chính nó có thể chứa dấu ngoặc kép, bạn sẽ cần phải thoát khỏi chúng - 'filename.gsub (/" /, '\\ "')' – gmcnaughton

2

tôi phát hiện ra rằng đội của tôi đang sử dụng csv_builder đá quý, cho phép bạn điều chỉnh tên của tập tin tải về bằng cách thiết lập @filename trong bộ điều khiển. Vẫn sẽ trao giải đáp chính xác cho bất cứ ai có thể giải thích lý do tại sao tôi nhận được hành vi được mô tả trong OP.

1

Tôi không thấy nơi bạn đang thực sự gửi/kết xuất đầu ra ... Có phải đó là tệp .csv.erb hay gì đó không? Hoặc sử dụng csv_builder làm câu trả lời khác? Đó có thể là lừa.

Tôi nghĩ ra điều tương tự sẽ hiển thị đầu ra .xlsx. Khi tôi đã có tệp trên đĩa, tôi có thể thực hiện việc này:

def example 
    respond_to do |format| 
    format.xlsx do 
     path = some_method_generating_xlsx_file 
     headers['Content-Disposition'] = "attachment; filename=test.xlsx" 
     render :text => File.binread(path), :content_type => XLSX_MIME_TYPE 
    end 
    end 
end 

trong bộ điều khiển của tôi và nó hoạt động tốt. Có lẽ các tiêu đề bị che khuất bởi việc tạo mẫu.

0

Cá nhân tôi không sử dụng render cho loại nội dung này - Tôi thích sử dụng send_data. Dưới đây là ví dụ:

send_data data, :type => 'text/csv', :disposition => 'attachment; filename=my_file_name.csv'