由獲取的file.type爲空字符串引伸瀏覽器是如何獲取文件的MIME類型

前言

  今天項目上遇到了一個問題,用戶須要導入一個從咱們服務器上下載的EXCEL文件,前端根據獲取到的文件的type屬性進行判斷是否能夠上傳["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel"],可是在某一個用戶的電腦上卻出現了經過<input type="file">獲取到的file對象中,type屬性爲"",因而開始找各類資料但願瞭解瀏覽器是如何獲取這個type屬性的,爲何同一個文件不一樣的電腦獲取到的屬性不同。前端

MIME Type是什麼

  根據MDN上的說明,MIME Type (Multipurpose Internet Mail Extensions (MIME) type)是一種標準化的方式來表示文檔的性質和格式。它在IETF RFC 6838中進行了定義和標準化。
  瀏覽器一般使用MIME類型(而不是文件擴展名)來肯定如何處理文檔;所以服務器設置正確以將正確的MIME類型附加到響應對象的頭部是很是重要的。因此瀏覽器中<input type="file">獲取到的file對象中的type屬性實際上是文件的MIME Type。算法

Chrome獲取MIME類型

  在chromium開源代碼中 https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=314 314-318行中提到了:瀏覽器

// We implement the same algorithm as Mozilla for mapping a file extension to
  // a mime type.  That is, we first check a hard-coded list (that cannot be
  // overridden), and then if not found there, we defer to the system registry.
  // Finally, we scan a secondary hard-coded list to catch types that we can
  // deduce but that we also want to allow the OS to override.

  Chrome實現了與Mozilla相同的算法,將文件擴展名映射到MIME類型。
首先,Chrome會檢測一個硬編碼列表(不能被覆蓋)源碼中的kPrimaryMappings,而後若是沒有找到符合的,Chrome會從操做系統註冊表中找,最後會掃描一個二級硬編碼列表,源碼中的kSecondaryMappings,用來捕獲能夠推斷可是也但願容許操做系統覆蓋的類型。
  例如:從安裝了Microsoft Excel的Windows系統上傳CSV文件時,Chrome會將其報告爲application/vnd.ms-excel。這是由於.csv未在第一個硬編碼列表中指定,所以瀏覽器會回退到系統註冊表。HKEY_CLASSES_ROOT\.csv有一個名爲的值Content Type設置爲application/vnd.ms-excel服務器

總結

  前言中遇到的問題瀏覽器中獲取不到type屬性不必定是代碼的緣由,而是系統中所安裝的Microsoft Excel軟件或註冊表的緣由,另外在MDN中的File對象中也找到這也一句描述:基於當前的實現,瀏覽器不會實際讀取文件的字節流,來判斷它的媒體類型。它基於文件擴展來假設;重命名爲 .txt 的 PNG 圖像文件爲 "text/plain" 而不是 "image/png" 。並且,file.type 僅僅對常見文件類型可靠。例如圖像、文檔、音頻和視頻。不常見的文件擴展名會返回空字符串。開發者最好不要依靠這個屬性,做爲惟一的驗證方案。app

相關文章
相關標籤/搜索