Golang Header 中的 UTF-8 檔名
Toby
Toby

一般來說如果你想讓 Golang 去 Serve 一個 File 你會在檔頭加入以下兩行:

w.Header().Set("Content-Disposition", "attachment; filename=" + filepath.Base(realFilepath))
w.Header().Set("Content-Type", r.Header.Get("Content-Type"))

這樣瀏覽器就不會播放多媒體檔案而是轉為下載模式。然而,對於一些含有特別字元 / 空格的檔案名稱,一般瀏覽器並無法完整讀取整個檔名,例如:

Chōcho - Authentic Symphony (Acoustic ver.).mp4
//檔案名稱下載時因為空格會被 Firefox 讀取成
Chōcho

而如果要解決這個問題,你可以使用 Golang 的 url.QueryEscape( ) 功能,把檔案名稱先轉換為 URL Safe 的名稱,但是這會出現另一個問題,例如上面的例子經過 QueryEscape 之後會變成這樣

Chōcho+-+Authentic+Symphony+(Acoustic+ver.).mp4

這是因為雖然標準裡面有寫到 URL Encode + 跟 ” “(空格)是相等的,但是很多主流瀏覽器對 URL Encode 的解讀只有 %20 而已,所以要解決這問題你就只能夠再把 + 替換成 %20 ,完整的代碼如下:

w.Header().Set("Content-Disposition", "attachment; filename*=UTF-8''" + strings.ReplaceAll(url.QueryEscape(filepath.Base(realFilepath)),"+","%20"))
w.Header().Set("Content-Type", r.Header.Get("Content-Type"))

那你可能會說你的 + 號不就是不見了嗎?嗯,沒錯,可是你有更好的解決方法嗎?