由 ASP.NET 伺服器端傳回檔案內容,需指定適當的 ContentType,瀏覽器才會將其視為圖檔、HTML、CSS 或 JavaScript 處理。過去我都是土法煉鋼,取得副檔名再用 switch … case 針對已知檔案種類列舉對應 ContentType,像這樣:

string contentType = "";
switch (fileName.Split('.').Last())
{
    case "jpg":
        contentType="image/jpeg";
        break;
    case "gif":
        contentType="image/gif";
        break;
    case "png":
        contentType="image/png";
        break;
    case "htm":
        contentType="text/html";
        break;
    case "css":
        contentType="text/css";
        break;
    case "js":
        contentType="text/javascript";
        break;
    default:
        throw new ApplicationException("Not supperted file type!");
}

隨便搜尋我的舊文章就能找到應用案例: 淺嚐Data URIHTML5 Canvas的Origin-Clean安全原則

最近發現好東西,.NET 4.5 起 System.Web 內建的 MimeMapping.GetMimeMapping() 可以直接將檔名(注意: 是檔名不是副檔名)對應成 ContentType,不用再自己徒手硬刻:

所以,文章開頭的程式邏輯可以簡化成:

if (!"jpg,gif,png,htm,css,js".Split(',').Contains(fileName.Split('.').Last())
    throw new ApplicationException("Not supperted file type!");
var contentType=MimeMapping.GetMimeMapping(fileName);

順便補充,從 ASP.NET WebForm 傳回 jpg、png 等圖檔,ContentType 已指定為 image/jpeg、image/png,若希望瀏覽器不要直接顯示而是下載另存檔案,可透過 Content-Disposition Header 搞定:
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + Server.UrlEncode(fileName) + "\"");
如果是 ASP.NET MVC Action,直接使用 return File(byteArray, contentType, fileName),MVC 會在背後搞定 ContentType 及 ContentDisposition Header,是最省事的做法。

延伸閱讀:


Comments

# by demo

MVC 的強制下載應該是可以很簡單的使用 return File(fileContents,contentType,fileDownloadName) 有給 file download name 即可

# by Jeffrey

to demo, 對,我熊熊忘記了。已補充於本文,感謝提醒。

Post a comment