mime-types vs http-errors vs content-disposition vs content-type vs mime vs type-is
HTTPヘッダーとMIMEタイプ処理のためのNode.jsユーティリティパッケージ比較
mime-typeshttp-errorscontent-dispositioncontent-typemimetype-is類似パッケージ:

HTTPヘッダーとMIMEタイプ処理のためのNode.jsユーティリティパッケージ比較

content-dispositioncontent-typehttp-errorsmimemime-typestype-is はすべて、Node.jsアプリケーションにおけるHTTPプロトコルやMIMEタイプの扱いを補助する軽量なユーティリティパッケージです。これらのパッケージは、主にExpressなどのWebフレームワークの内部やミドルウェアで使われ、開発者が手動でHTTPヘッダーやエラーレスポンスを安全かつ正確に構築できるようにします。たとえば、content-dispositionはファイルダウンロード時のContent-Dispositionヘッダーを生成し、http-errorsはHTTPステータスコードに対応した標準的なエラーオブジェクトを提供します。これらは単体ではアプリケーションの主要機能を担いませんが、堅牢で仕様準拠のHTTP通信を実現するための重要な基盤となります。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
mime-types166,299,4671,45422.9 kB204ヶ月前MIT
http-errors102,331,4811,55519.1 kB164ヶ月前MIT
content-disposition90,884,79323819.2 kB154ヶ月前MIT
content-type014310.5 kB63年前MIT
mime02,352161 kB16ヶ月前MIT
type-is022721.3 kB131年前MIT

HTTPヘッダーとMIMEタイプ処理のためのNode.jsユーティリティパッケージ比較

Node.jsでWebアプリケーションを構築する際、HTTPヘッダーやMIMEタイプの扱いは意外と面倒です。手動で文字列を組み立てると、RFC違反やセキュリティ脆弱性(例:CRLFインジェクション)を引き起こすリスクがあります。content-dispositioncontent-typehttp-errorsmimemime-typestype-is は、こうした低レベルの処理を安全かつ正確に行うための専門的なユーティリティパッケージです。これらは互いに補完し合い、多くのWebフレームワーク(特にExpress)の内部で広く使われています。以下では、各パッケージの役割と使いどころを具体的なコードとともに解説します。

📥 ファイルダウンロードヘッダー: content-disposition

ファイルをダウンロードさせる際、Content-Dispositionヘッダーでファイル名を指定しますが、ユーザー入力(例:ファイル名)をそのまま使うと危険です。content-dispositionは、RFC 6266に準拠した安全なヘッダー生成を提供します。

// content-disposition
const contentDisposition = require('content-disposition');

// 危険なファイル名(改行文字を含む)も安全にエスケープ
const filename = 'report\n.txt';
const header = contentDisposition(filename);
// -> 'inline; filename="report_.txt"; filename*=UTF-8\'\'report%0A.txt'

res.setHeader('Content-Disposition', header);

手動でヘッダーを組み立てると、改行文字が含まれているとCRLFインジェクション攻撃の原因になります。このパッケージを使えば、そうしたリスクを回避できます。

🧾 MIMEタイプの解析と生成: content-type

Content-Typeヘッダーは、MIMEタイプとパラメータ(例:charset)で構成されます。content-typeは、これを正確にパース・再構築します。

// content-type
const contentType = require('content-type');

// ヘッダーをパース
const obj = contentType.parse('text/html; charset=utf-8');
// -> { type: 'text/html', parameters: { charset: 'utf-8' } }

// オブジェクトからヘッダーを再構築
const header = contentType.format(obj);
// -> 'text/html; charset=utf-8'

自分で正規表現で分割すると、引用符や特殊文字の処理を間違えやすいですが、このパッケージはRFC 7231に完全準拠しています。

❌ 標準化されたHTTPエラー: http-errors

HTTPステータスコードに対応したエラーオブジェクトを簡単に作成できます。Expressのエラーハンドリングと連携しやすい設計です。

// http-errors
const createError = require('http-errors');

// 404エラーを生成
const notFound = createError(404, 'Page not found');
// -> Errorオブジェクト(statusCode: 404, message: 'Page not found')

// 500エラーを生成
const serverError = createError.InternalServerError('Database down');

// Expressのエラーハンドラで使用
app.use((err, req, res, next) => {
  res.status(err.status || 500).json({ error: err.message });
});

独自のエラークラスを定義する代わりに、このパッケージを使うことで、HTTP仕様に沿った一貫したエラーレスポンスを実装できます。

📁 拡張子とMIMEタイプの変換: mime

ファイル拡張子からMIMEタイプを取得したり、逆にMIMEタイプから拡張子を取得したりできます。

// mime
const mime = require('mime');

// 拡張子からMIMEタイプ
const type = mime.getType('file.txt');
// -> 'text/plain'

// MIMEタイプから拡張子
const ext = mime.getExtension('text/html');
// -> 'html'

静的ファイルサーバーを実装する際に、リクエストされたファイルの拡張子に基づいてContent-Typeを設定するのに便利です。

🔍 MIMEタイプのメタデータ取得: mime-types

MIMEタイプそのものに関する情報を取得するのに特化しています。拡張子操作は不要な場合に使います。

// mime-types
const mimeTypes = require('mime-types');

// MIMEタイプの標準charsetを取得
const charset = mimeTypes.charset('text/html');
// -> 'UTF-8'

// MIMEタイプがテキストベースか判定
const isText = mimeTypes.contentType('text/plain');
// -> 'text/plain; charset=utf-8'(charsetが追加される)

mimeパッケージと異なり、拡張子との双方向マッピングは提供しません。MIMEタイプの属性(例:charset)だけが必要なら、こちらの方が軽量です。

🔎 リクエストのMIMEタイプ検査: type-is

リクエストのContent-Typeヘッダーを検査し、特定のMIMEタイプに一致するかを判定します。ワイルドカードやサブタイプもサポート。

// type-is
const typeis = require('type-is');

// リクエストオブジェクト(headers['content-type']を持つ)を想定
const req = { headers: { 'content-type': 'application/json' } };

// JSONかどうかを判定
if (typeis.is(req, ['json', 'urlencoded'])) {
  // 処理
}

// ワイルドカードで判定
if (typeis.is(req, 'application/*')) {
  // application/以下のすべてにマッチ
}

APIエンドポイントで、受け付けるボディ形式をバリデーションするミドルウェアを書く際に重宝します。

🔄 連携パターン: 実際のユースケース

これらのパッケージは単体ではなく、組み合わせて使うことがよくあります。たとえば、ファイルアップロードAPIでは次のように連携します。

// ファイルアップロードAPIの例
const httpErrors = require('http-errors');
const typeis = require('type-is');
const mimeTypes = require('mime-types');

app.post('/upload', (req, res, next) => {
  // 1. リクエストのContent-Typeを検査
  if (!typeis.is(req, 'multipart/form-data')) {
    return next(httpErrors.BadRequest('Expected multipart/form-data'));
  }

  // ...ファイル処理...

  // 2. ダウンロード用のContent-Dispositionを生成
  const contentDisposition = require('content-disposition');
  res.setHeader('Content-Disposition', contentDisposition('uploaded-file.jpg'));

  // 3. Content-Typeを設定
  const contentType = require('content-type');
  res.setHeader('Content-Type', contentType.format({
    type: 'image/jpeg',
    parameters: {}
  }));

  res.send(fileBuffer);
});

このように、各パッケージが得意な領域をカバーし合うことで、堅牢でメンテナンスしやすいHTTP処理が実現できます。

⚠️ 注意点と避けるべきパターン

  • mime vs mime-types: 拡張子操作が必要ならmime、MIMEタイプの属性だけならmime-typesを使いましょう。両方を同時に使う必要はほとんどありません。
  • 手動ヘッダー構築: Content-DispositionContent-Typeを文字列連結で組み立てるのは避けましょう。必ず専用パッケージを使ってください。
  • エラー処理の一貫性: http-errorsを使えば、エラーオブジェクトの形式が統一され、ミドルウェアでの処理が簡単になります。

📊 まとめ: 各パッケージの主な用途

パッケージ主な用途典型的な使用場面
content-disposition安全なContent-Dispositionヘッダー生成ファイルダウンロードAPI
content-typeContent-Typeヘッダーのパース・生成リクエスト/レスポンスのMIME処理
http-errorsHTTPステータスコード付きエラー生成APIエラーレスポンス
mime拡張子 ↔ MIMEタイプ変換静的ファイルサーバー
mime-typesMIMEタイプのメタデータ取得MIME属性(例:charset)の参照
type-isリクエストのMIMEタイプ検査ボディ形式のバリデーション

💡 最終的なアドバイス

これらのパッケージはどれも非常に軽量で、目的が明確に分かれています。プロジェクトでHTTP通信を扱うなら、それぞれの役割に応じて適切に使い分けることで、バグやセキュリティ問題を未然に防げます。特に、ユーザー入力が関わるヘッダー構築(例:ファイル名)では、必ずcontent-dispositionのような専用ライブラリを使うことを強く推奨します。手動実装は一見簡単ですが、長期的に見てメンテナンスコストとリスクが高くなります。

選び方: mime-types vs http-errors vs content-disposition vs content-type vs mime vs type-is

  • mime-types:

    mime-typesは、MIMEタイプに関する情報を取得する必要があるが、ファイル拡張子との双方向マッピングは不要な場合に適しています。たとえば、'text/html'の標準的なcharsetを取得するなど、MIMEタイプそのものに関するメタデータ操作に特化しています。mimeよりも軽量で、拡張子操作が不要ならこちらが効率的です。

  • http-errors:

    http-errorsは、HTTPステータスコード(例:404, 500)に対応したエラーオブジェクトを一貫して生成したい場合に最適です。Expressのエラーハンドリングミドルウェアと連携しやすく、エラーメッセージやスタックトレースを含む標準化された形式を提供します。独自のエラークラスを定義する手間を省き、HTTP仕様に沿ったレスポンスを簡単に実装できます。

  • content-disposition:

    content-dispositionは、ファイルダウンロード時にContent-Dispositionヘッダーを安全に生成したい場合に選択します。特に、ユーザー入力(例:ファイル名)を含むヘッダー値を構築する際に、RFC 6266に準拠したエスケープ処理を自動で行う点が重要です。手動でヘッダー文字列を組み立てるよりも、セキュリティリスク(例:CRLFインジェクション)を回避できます。

  • content-type:

    content-typeは、Content-Typeヘッダーの解析または生成が必要な場合に使用します。このパッケージは、MIMEタイプとパラメータ(例:charset=utf-8)を正確に分離・再構築でき、フォーマットエラーを防ぎます。自分で正規表現でパースする代わりに、信頼性の高い標準ライブラリを使うことで、バグのリスクを減らせます。

  • mime:

    mimeは、ファイル拡張子からMIMEタイプを取得したり、逆にMIMEタイプから拡張子を取得したりする必要がある場合に選択します。このパッケージは内部でmime-dbを使用しており、広範なMIMEタイプデータベースを備えています。ただし、静的アセット配信など、拡張子ベースのMIME推論が中心の用途に特化しています。

  • type-is:

    type-isは、リクエストのContent-Typeヘッダーを検査して、特定のMIMEタイプやワイルドカード(例:application/*)に一致するかを判定したい場合に使用します。ミドルウェア内でリクエストのボディ形式をバリデーションする際に便利で、複雑な条件分岐を簡潔に記述できます。手動でヘッダー文字列を比較するより、MIMEの階層構造を正しく考慮した判定が可能です。

mime-types のREADME

mime-types

NPM Version NPM Downloads Node.js Version Build Status Test Coverage

The ultimate javascript content-type utility.

Similar to the mime@1.x module, except:

  • No fallbacks. Instead of naively returning the first available type, mime-types simply returns false, so do var type = mime.lookup('unrecognized') || 'application/octet-stream'.
  • No new Mime() business, so you could do var lookup = require('mime-types').lookup.
  • No .define() functionality
  • Bug fixes for .lookup(path)

Otherwise, the API is compatible with mime 1.x.

Install

This is a Node.js module available through the npm registry. Installation is done using the npm install command:

$ npm install mime-types

Note on MIME Type Data and Semver

This package considers the programmatic api as the semver compatibility. Additionally, the package which provides the MIME data for this package (mime-db) also considers it's programmatic api as the semver contract. This means the MIME type resolution is not considered in the semver bumps.

In the past the version of mime-db was pinned to give two decision points when adopting MIME data changes. This is no longer true. We still update the mime-db package here as a minor release when necessary, but will use a ^ range going forward. This means that if you want to pin your mime-db data you will need to do it in your application. While this expectation was not set in docs until now, it is how the pacakge operated, so we do not feel this is a breaking change.

If you wish to pin your mime-db version you can do that with overrides via your package manager of choice. See their documentation for how to correctly configure that.

Adding Types

All mime types are based on mime-db, so open a PR there if you'd like to add mime types.

API

var mime = require('mime-types')

All functions return false if input is invalid or not found.

mime.lookup(path)

Lookup the content-type associated with a file.

mime.lookup('json') // 'application/json'
mime.lookup('.md') // 'text/markdown'
mime.lookup('file.html') // 'text/html'
mime.lookup('folder/file.js') // 'application/javascript'
mime.lookup('folder/.htaccess') // false

mime.lookup('cats') // false

mime.contentType(type)

Create a full content-type header given a content-type or extension. When given an extension, mime.lookup is used to get the matching content-type, otherwise the given content-type is used. Then if the content-type does not already have a charset parameter, mime.charset is used to get the default charset and add to the returned content-type.

mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
mime.contentType('file.json') // 'application/json; charset=utf-8'
mime.contentType('text/html') // 'text/html; charset=utf-8'
mime.contentType('text/html; charset=iso-8859-1') // 'text/html; charset=iso-8859-1'

// from a full path
mime.contentType(path.extname('/path/to/file.json')) // 'application/json; charset=utf-8'

mime.extension(type)

Get the default extension for a content-type.

mime.extension('application/octet-stream') // 'bin'

mime.charset(type)

Lookup the implied default charset of a content-type.

mime.charset('text/markdown') // 'UTF-8'

var type = mime.types[extension]

A map of content-types by extension.

[extensions...] = mime.extensions[type]

A map of extensions by content-type.

License

MIT