LoginSignup
15
17

More than 5 years have passed since last update.

Content-Disposition の日本語問題

Last updated at Posted at 2013-05-01

たとえば rails で、

send_file(filename: "日本語.pdf")

のように日本語指定するとブラウザによってうまくいかない場合がある。
この問題は検索してみるとなかなかやっかいなのだが、いちおう現時点では
http://greenbytes.de/tech/tc2231/#attwithfn2231utf8
これがファイナルアンサーと思われる。

しかし rails3.2 rails4.0 時点での send_file は、この記法

Content-Disposition: attachment; filename*=UTF-8''foo-%c3%a4-%e2%82%ac.html

に対応していない。(see rfc2231)

そこでモンキーパッチを当てよう。

config/initializers/send_file_with_utf8.rb
module ActionController
  module DataStreaming
    def send_file_headers_with_utf8!(options)
      send_file_headers_without_utf8!(options)
      match = /(.+); filename="(.+)"/.match(headers['Content-Disposition'])
      encoded = URI.encode_www_form_component(match[2])
      headers['Content-Disposition'] = "#{match[1]}; filename*=UTF-8''#{encoded}" unless encoded == match[2]
    end
    alias_method_chain :send_file_headers!, :utf8
  end
end

一発パッチコマンドはこちら↓

wget https://gist.github.com/kuboon/5494463/raw/31d80be6dc23eac2bc05d996df1e0293ae001124/send_file_with_utf8.rb -P config/initializers/

update: 2013/05/01 Windows版 safari ではうまくいかないことが判明した。

Content-Disposition をどんなに工夫しても無視され、URL の末尾のファイル名が使用されるっぽい。そこで、まず filename をオプショナルに受け取れるように routes.rb を修正

config/routes.rb
  get "/pdf/:id(/:filename)" => "pdfs#show"

action に以下のように、自分自身にリダイレクトするコードを書く。(gem 'useragent' を使用)

  user_agent = UserAgent.parse(request.env['HTTP_USER_AGENT'])
  if params[:filename].nil? && user_agent.browser == "Safari" && user_agent.platform == "Windows" 
    # && user_agent.version <= "5.1.7" 新バージョンで修正されたら uncomment
    return redirect_to pdf_path(params[:id], filename)
  end

さすがにこの処理をモンキーパッチで書くのは黒魔法過ぎるのでここで妥協。

15
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17