1. ホーム
  2. forms

[解決済み] アップロードされたファイルのMIMEタイプは、ブラウザによってどのように決定されるのですか?

2023-03-06 13:13:01

質問

ユーザーが .zip ファイルをアップロードする必要がある Web アプリがあります。 サーバー側で、アップロードされたファイルの MIME タイプをチェックし、それが application/x-zip-compressed または application/zip .

これは、Firefox と IE で正常に動作しました。 しかし、同僚がテストしたところ、彼は Firefox で失敗しました (送信された MIME タイプは " のようなものでした)。 application/octet-stream のようなものでした)、Internet Explorerではうまくいきました。 私たちのセットアップは、IE8、FF 3.5.1、すべてのアドオン無効、Win XP SP3、ネイティブの .zip ファイル ハンドラとして WinRAR をインストール (これが関連しているかどうかは不明) という同一のものでした。

そこで質問なのですが。 ブラウザはどのように送信する MIME タイプを決定するのでしょうか?

注: 私は、MIME タイプがブラウザによって送信され、したがって、信頼できないことを知っています。 主に、zip ファイルとして非 zip ファイルを開こうとしたときに表示されるメッセージよりも親切なエラー メッセージを表示し、(おそらく重い) zip ファイル ライブラリをロードしないようにするために、便宜上それをチェックしているだけです。

どのように解決するのですか?

クローム

クローム (執筆時点ではバージョン 38) には、MIME タイプを判断する方法が 3 つあり、一定の順序で判断されます。以下のスニペットは、ファイル src/net/base/mime_util.cc にある、メソッド MimeUtil::GetMimeTypeFromExtensionHelper .

// 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.

ハードコードされたリストは、ファイルの少し前にあります。 https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 ( kPrimaryMappingskSecondaryMappings ).

例: Microsoft Excel がインストールされている Windows システムから CSV ファイルをアップロードする場合、Chrome は次のように報告します。 application/vnd.ms-excel . これは .csv が最初のハードコードされたリストで指定されていないため、 ブラウザはシステムレジストリにフォールバックします。 HKEY_CLASSES_ROOT\.csv という名前の値には Content Type という値が設定されており application/vnd.ms-excel .

インターネットエクスプローラー

再び同じ例を使うと、ブラウザは次のように報告します。 application/vnd.ms-excel . 私は、Internet Explorer の (執筆時点ではバージョン 11) はレジストリを使用します。Chrome や Firefox のようにハードコードされたリストを使用する可能性もありますが、そのクローズド ソースの性質上、検証は困難です。

Firefox

Chrome のコードで示したように、Firefox では (執筆時点ではバージョン 32) は同様の方法で動作します。ファイルからのスニペット uriloader\exthandler\nsExternalHelperAppService.cpp メソッド nsExternalHelperAppService::GetTypeFromExtension

// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category

ハードコードされたリストは、ファイルの前の方、441行目付近のどこかにあります。あなたが探しているのは defaultMimeEntriesextraMimeEntries .

現在のプロファイルでは、ブラウザは text/csv にエントリがあるので mimeTypes.rdf にそのエントリがあるからです (上記のリストの項目 2)。この項目がない新しいプロファイルを使用すると、ブラウザは application/vnd.ms-excel と報告されます (リストの 3 番目)。

概要

ブラウザのハードコードされたリストはかなり限定的です。多くの場合、ブラウザによって送信される MIME タイプは OS によって報告されるものになります。そしてこれがまさに、質問にあるように、ブラウザによって報告された MIME タイプが信頼できない理由なのです。