概要
devServer は .html .css .js .json .xml .svg 以外の拡張子に Content-Type を設定しません。その結果、@hono/node-server の既定値である text/plain; charset=UTF-8 がそのまま返ります。これにより Firefox で動画が再生できません。
再現
htdocs/ に画像と動画を置いて devServer を起動し、レスポンスヘッダを確認します。
$ curl -s -D - -o /dev/null http://localhost:8000/img/foo.svg | grep -i content-type
content-type: image/svg+xml
$ curl -s -D - -o /dev/null http://localhost:8000/img/foo.webp | grep -i content-type
content-type: text/plain; charset=UTF-8
$ curl -s -D - -o /dev/null http://localhost:8000/video/foo.mp4 | grep -i content-type
content-type: text/plain; charset=UTF-8
この状態で <video src="/video/foo.mp4"> を Firefox で開くと再生されません。同じファイルを python3 -m http.server で配信すると(content-type: video/mp4 が返る)、Firefox で正常に再生されます。
原因
3段構えです。
packages/kamado/src/server/route.ts の switch (ext) が上記6拡張子しか扱っておらず、それ以外は ctx.header('Content-Type', ...) を通りません
- レスポンスは
ctx.body() で返していますが、hono の ctx.body() は Content-Type を付与しません(new Response(data, { status, headers }) を呼ぶだけ)
@hono/node-server が送信直前に既定値を埋めます
// @hono/node-server/dist/index.mjs buildOutgoingHttpHeaders()
res['content-type'] ??= 'text/plain; charset=UTF-8';
Content-Type 未設定のまま応答すると、必ず text/plain; charset=UTF-8 になります。
影響
- 上記6拡張子以外のすべてのファイルが誤った
Content-Type で配信されています
- Firefox で動画・音声が再生できません
- 画像は
<img> のブラウザ側 MIME sniffing で表示されるため、問題に気づけません(SVG は sniffing 対象外ですが、現状 switch に含まれているため影響を受けません)
- ビルド成果物を実サーバーに置いた場合は正しい
Content-Type が返るため、devServer でのみ挙動が異なります
環境
概要
devServer は
.html.css.js.json.xml.svg以外の拡張子にContent-Typeを設定しません。その結果、@hono/node-serverの既定値であるtext/plain; charset=UTF-8がそのまま返ります。これにより Firefox で動画が再生できません。再現
htdocs/に画像と動画を置いて devServer を起動し、レスポンスヘッダを確認します。この状態で
<video src="/video/foo.mp4">を Firefox で開くと再生されません。同じファイルをpython3 -m http.serverで配信すると(content-type: video/mp4が返る)、Firefox で正常に再生されます。原因
3段構えです。
packages/kamado/src/server/route.tsのswitch (ext)が上記6拡張子しか扱っておらず、それ以外はctx.header('Content-Type', ...)を通りませんctx.body()で返していますが、hono のctx.body()はContent-Typeを付与しません(new Response(data, { status, headers })を呼ぶだけ)@hono/node-serverが送信直前に既定値を埋めますContent-Type未設定のまま応答すると、必ずtext/plain; charset=UTF-8になります。影響
Content-Typeで配信されています<img>のブラウザ側 MIME sniffing で表示されるため、問題に気づけません(SVG は sniffing 対象外ですが、現状switchに含まれているため影響を受けません)Content-Typeが返るため、devServer でのみ挙動が異なります環境
dev(9479ebd)で確認