Web 下載文件名亂碼解決以及多瀏覽器兼容方案

在 web 開發中,經常我們會遇到如導出或者下載網頁這種需求,但是往往會遇到在chrome瀏覽器下載的文件名正常,但是到 firefox,Safari上卻亂碼的情況,經過網上的資料多次研究,最終總結出瞭如下的方法,代碼如下:

/// <summary>
/// 瀏覽器下載文件,完整文件下載,不支持分片下載,爲了兼容safari,下載url請保持這個格式,
/// 否則safari下載會亂碼:/api/WebFile/DownloadFile/encodeURIComponent(要下載的文件名.txt),即末尾這一段路徑爲文件名,
/// 如果需要取值則通過[FromRoute]實現
/// </summary>
/// <param name="response">響應</param>
/// <param name="fileName">下載文件名</param>
/// <param name="bodyStream">文件流</param>
/// <returns></returns>
public static async Task DownloadFileAsync(HttpResponse response, string fileName, Stream bodyStream)
{
    //文件名UTF 8 編碼
    fileName = HttpUtility.UrlEncode(fileName, Encoding.UTF8);
    fileName = fileName.Replace("+", "%20");

    //指定響應類型
    response.ContentType = "application/octet-stream; charset=UTF-8";
    response.Headers.Add("Cache-Control", "no-cache");
    response.Headers.Add("Pragma", "no-cache");
    response.Headers.Add("Content-Disposition", $"attachment;filename={fileName};filename*=utf-8''{fileName};");//不同瀏覽器只會用自己可以識別的格式
    response.ContentLength = bodyStream.Length;
    await bodyStream.CopyToAsync(response.Body);
    bodyStream.Close();
}

上面是一個幫助類,對外的接口名可以自定義,如 /api/File/Export?fileId=5,然後路由對應的方法實現裏面調用上面的方法即可。但是這種方式在Safari瀏覽器下下載下來的文件名仍然會有亂碼,解決辦法是把接口定義爲 /api/File/Export/圖片.png?fileId=5 這種格式,即url末尾段是想要下載的實際文件名即可,注意文件名記得用 js 函數 encodeURIComponent(圖片.png) 形式編碼,否則文件名帶有如 % 字符會報錯。這樣就能完美下載文件了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章