• Content-Typeはfile名の拡張子で決めずHTTP responseで返す内容に合わせる

Content-Typeはfile名の拡張子で決めずHTTP responseで返す内容に合わせる

公開日: 執筆:佐藤

Content-Typeは、HTTP responseの本文がどのmedia typeであるかを示すheaderです。file名が.jsonなら必ずJSON、.pdfなら必ずPDFになるわけではありません。serverが実際に返す本文とheaderが食い違えば、browser、JavaScript、downloadした人は内容を正しく扱えません。拡張子、アップロード画面、response headerを別々に確認します。

ページが表示されるから設定は正しい、と決めるのも早すぎます。HTMLを期待するURLがlogin画面のHTMLを返している、JSONを期待するAPIがerror pageを返している、PDF downloadのURLが別のfileを返していることがあります。見る側が何の形式として受け取り、どの操作へ進むかを考えて、responseを作ります。

Content-Typeは本文の扱いを伝えるheaderである

RFC 7231は、Content-Typeをrepresentationのmedia typeを示すheader fieldとして定めています。text/htmlならHTML document、application/jsonならJSON data、image/jpegならJPEG imageというように、受け取る側が本文をどう扱うかの手掛かりになります。text形式では、必要に応じて文字コードのparameterも示します。

説明用の仮例として、資料請求の一覧をJavaScriptで取得するURLを考えます。正常なときにJSONを返すなら、本文がJSONであり、Content-TypeもJSONを示すようにします。認証が必要な場合にlogin pageのHTMLを返すなら、そのresponseはHTMLです。URLの末尾に.jsonが付いていても、受け取ったJavaScriptはJSONとして読めません。HTTP statusとContent-Type、本文を並べて確認します。

この区別をしないと、browser上では「JSONの読み込みに失敗した」としか見えない不具合になります。本当の原因は、login状態、redirect、server error、URLの打ち間違いかもしれません。JSONを読む処理だけを直すのでなく、networkのresponse headerと本文を開き、何が返ったかを確かめます。

拡張子とuploadを信用しすぎない

画像やPDFをuploadするとき、file名の拡張子は運用上の目印になります。しかし拡張子だけで中身を保証しません。uploadを受けるserverは、許可するmedia type、保存するfile名、公開するURL、downloadするときのheaderを分けて扱います。利用者が付けたfile名をそのまま公開URLやHTMLへ使う場合は、表示する場所に合った処理も必要です。

たとえば、会社案内PDFをcompany-profile.pdfとして公開するなら、download URLを開いたときにPDFの本文とPDFを示すContent-Typeが返るかを確認します。誤ってHTMLのerror pageを200 OKで返していれば、利用者はPDFを開けず、問い合わせも増えます。fileがserver上にあること、CMSのmedia libraryに登録されていること、公開URLが正しいresponseを返すことは別の確認です。

画像でも同じです。画像のURLがimage/pngを返すと思っていても、permission errorやnot found pageのHTMLを返す場合があります。img要素で画像が壊れて見えるときは、CSSだけを疑いません。画像URLを直接開き、status、Content-Type、本文を見ます。画像のfile名を直しても、server設定や公開範囲が間違っていれば表示は直りません。

downloadと画面表示で目的を分ける

資料を読ませるためにbrowser内で表示するのか、利用者の端末へ保存させるのかも先に決めます。Content-Typeは本文の形式を示し、downloadの扱いは別のresponse headerやbrowserの判断にも関係します。PDFを公開する目的が閲覧か保存かで、page内の案内、linkの文言、更新後の確認が変わります。

利用者が「会社案内を見る」と思ってlinkを開くなら、PDFなのかweb pageなのかをlinkの前に分かるようにします。容量が大きいfileなら、容量や形式を示す判断もあります。スマートフォンで読みにくい資料をPDFだけで出す場合は、重要な連絡先や申込み条件をHTML pageにも置くかを考えます。正しいContent-Typeを返すことと、読者が内容を利用しやすいことは別です。

外部のstorage serviceやCDNからfileを出す構成では、CMSの設定だけを見ません。公開URLがどのserverを通り、最後にどのheaderを返すかを確認します。移転やstorage変更のあと、古いURLがredirectされて別のcontent typeになることもあります。制作会社へuploadを任せるなら、元fileを渡した時点でなく、公開URLを開いて本文とheaderを確認した時点を完了にします。

変更後は成功時と失敗時を両方試す

確認は、正しいfileを一つ開くだけでは足りません。HTML page、JSONを返すURL、画像、PDFのように形式が違うURLを選び、期待するstatusとContent-Typeを記録します。次に、存在しないfileや権限のないURLを開き、error responseのstatusと本文が正しく分かるかを見ます。error pageを返す場合に、本来のfile typeを示すheaderが残っていないかも確認します。

JavaScriptから取得するJSONでは、HTTP statusが成功であること、Content-Typeが期待する形式であること、本文を読めること、必要な値があることを順に確かめます。途中の一つを省くと、server側の変更を画面側の不具合として追うことになります。利用者へ出すmessageは短くし、URL、status、response header、発生時刻などは調査用に残します。

WordPressでmedia fileを扱う場合は、theme、plugin、hostingがheaderを変える場所になります。管理画面から見えるfile名だけでなく、loginしていない状態で公開URLを開きます。site移転、HTTPS化、cache設定を変えた直後は、画像、PDF、JSONのURLをまとめて確認します。page本文が正しくても、添付fileのresponseが壊れれば資料を読む経路は止まります。

最初の一手は、利用者が開くURLをHTML、JSON、画像、download fileに分け、各URLが返すべきContent-Typeを書き出すことです。実際のresponse headerと本文を並べ、違うものから直します。拡張子を整えることより、公開URLが利用者へ何を返しているかを確認します。

戻る