たとえば 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
さすがにこの処理をモンキーパッチで書くのは黒魔法過ぎるのでここで妥協。