ブラウザでWebサイトを開くと、瞬時にページが表示されますよね。
でも、その裏では「HTTPヘッダー」という見えない情報がやり取りされているんです。これがないと、Webページは正しく表示されません。
「ヘッダー?難しそう…」と思うかもしれませんが、基本を理解すれば意外とシンプル。
この記事では、HTTPヘッダーの仕組みから実践的な使い方まで、初心者の方にも分かりやすく解説していきます。
Web開発を始めたばかりの方も、トラブルシューティングに悩んでいる方も、ぜひ最後まで読んでみてください。
HTTPヘッダーとは
基本的な定義
HTTPヘッダーとは、WebブラウザとWebサーバーがやり取りする際に送る「付加情報」のことです。
手紙に例えるなら、本文がWebページの内容で、ヘッダーは封筒に書かれた送り主や宛先、配送方法などの情報。
役割
- どんな種類のデータか伝える
- データをどう処理すべきか指示する
- 認証情報を送る
- キャッシュの制御をする
本文(コンテンツ)だけでなく、これらの情報も一緒に送られているんです。
HTTPの通信の流れ
Webページを見るときの流れを見てみましょう。
ステップ1:リクエスト
ブラウザがサーバーに「このページをください」と要求します。このとき、リクエストヘッダーも一緒に送ります。
ステップ2:レスポンス
サーバーが「はい、どうぞ」とページを返します。このとき、レスポンスヘッダーも一緒に送ります。
ステップ3:表示
ブラウザがヘッダーの情報を読んで、適切にページを表示します。
このやり取りの中で、ヘッダーが重要な役割を果たしています。
ヘッダーの構造
ヘッダーは「名前: 値」という形式で書かれます。
基本的な書き方
Content-Type: text/html
Content-Length: 1234
Cache-Control: no-cache
コロン(:)の前が項目名、後ろが値です。シンプルですね。
リクエストヘッダーとレスポンスヘッダー
リクエストヘッダー
ブラウザからサーバーへ送る情報です。
どんな情報が含まれる?
- 使っているブラウザの種類
- 受け入れ可能なデータ形式
- 言語の優先順位
- 認証情報
- クッキー
「私はこんなブラウザを使っていて、こういうデータが欲しいです」という自己紹介のようなもの。
レスポンスヘッダー
サーバーからブラウザへ送る情報です。
どんな情報が含まれる?
- サーバーの種類
- データの形式
- データのサイズ
- キャッシュの指示
- セキュリティ設定
「このデータはこういう形式で、こう扱ってください」という説明書のようなものですね。
両方で使われる共通ヘッダー
どちらでも使われるヘッダーもあります。
共通ヘッダーの例
- Date(日時)
- Connection(接続の扱い方)
- Transfer-Encoding(転送方式)
主要なリクエストヘッダー
Host
どのサーバーにアクセスしたいか指定します。
例
Host: www.example.com
1つのサーバーで複数のサイトを運営している場合、このヘッダーで区別するんです。必須のヘッダーです。
User-Agent
使っているブラウザやOSの情報を伝えます。
例
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
サーバー側は、この情報を見てモバイル向けページを出したり、ブラウザ別の対応をしたりします。
Accept
受け入れ可能なデータ形式を伝えます。
例
Accept: text/html, application/xml, image/png
「HTMLでもXMLでもPNG画像でも表示できますよ」という意味です。
Accept-Language
優先する言語を伝えます。
例
Accept-Language: ja, en;q=0.9
日本語を最優先、英語は次点で受け入れるという意味。サーバーは、この情報を見て適切な言語のページを返します。
Cookie
以前サーバーから受け取ったクッキーを送り返します。
例
Cookie: session_id=abc123; user_pref=dark_mode
ログイン状態の維持や、ユーザー設定の保存に使われます。
Authorization
認証情報を送ります。
例
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
APIアクセスなどで、「私は正当なユーザーです」と証明するために使います。
Referer
どのページからアクセスしてきたか伝えます。
例
Referer: https://www.google.com/search?q=example
アクセス解析で「どこから来たか」を知るのに使われますね。
主要なレスポンスヘッダー
Content-Type
返すデータの種類を指定します。
例
Content-Type: text/html; charset=UTF-8
HTMLファイルで、文字コードはUTF-8ですよ、という意味。
よく使われる値
text/html
:HTMLページtext/css
:スタイルシートapplication/json
:JSON形式のデータimage/jpeg
:JPEG画像application/pdf
:PDFファイル
Content-Length
データのサイズを伝えます。
例
Content-Length: 12345
12,345バイトのデータが送られてきますよ、という意味。ブラウザは、進捗バーを表示するのにこの情報を使います。
Set-Cookie
ブラウザにクッキーを保存するよう指示します。
例
Set-Cookie: session_id=xyz789; Path=/; HttpOnly; Secure
セッション管理やユーザー設定の保存に使われます。
属性の意味
Path=/
:全てのパスで有効HttpOnly
:JavaScriptからアクセス不可(セキュリティ向上)Secure
:HTTPS通信でのみ送信
Cache-Control
キャッシュの扱いを指示します。
例
Cache-Control: max-age=3600, public
3600秒(1時間)はキャッシュを使ってOK、という指示。
よく使われる値
no-cache
:毎回サーバーに確認no-store
:キャッシュしないmax-age=秒数
:指定時間キャッシュ可能public
:誰でもキャッシュ可能private
:特定ユーザーのみキャッシュ可能
Location
リダイレクト先のURLを指定します。
例
Location: https://www.example.com/new-page
ページが移転したときなどに使います。
Server
サーバーの種類を伝えます。
例
Server: Apache/2.4.41 (Ubuntu)
セキュリティ上、詳細なバージョン情報は隠すことも多いです。
セキュリティ関連のヘッダー
Strict-Transport-Security(HSTS)
常にHTTPS接続を強制します。
例
Strict-Transport-Security: max-age=31536000; includeSubDomains
一度HTTPS接続すると、1年間はHTTPでアクセスしようとしても自動的にHTTPSになります。
X-Content-Type-Options
ブラウザにMIMEタイプを推測させない設定です。
例
X-Content-Type-Options: nosniff
セキュリティホールを防ぐために重要なヘッダー。
X-Frame-Options
他サイトに埋め込まれるのを防ぎます。
例
X-Frame-Options: DENY
クリックジャッキング攻撃を防ぐために使います。
設定値
DENY
:一切の埋め込みを禁止SAMEORIGIN
:同じサイト内なら許可ALLOW-FROM uri
:特定のサイトからなら許可
Content-Security-Policy(CSP)
読み込めるリソースを制限します。
例
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
自サイトのリソースと、信頼できるCDNからのスクリプトだけを許可する設定。
XSS(クロスサイトスクリプティング)攻撃を防ぐための強力な仕組みです。
X-XSS-Protection
ブラウザのXSS保護機能を有効にします。
例
X-XSS-Protection: 1; mode=block
古いブラウザ向けの保護機能。最近はCSPの使用が推奨されています。
キャッシュ制御のヘッダー
ETag
リソースの識別子です。
例
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ファイルが更新されたかどうか判断するために使います。
動作の流れ
- 初回アクセス時にETagを受け取る
- 次回アクセス時にETagを送る
- サーバーが変更なしなら304(変更なし)を返す
- ブラウザはキャッシュを使う
通信量を減らせますね。
Last-Modified
最終更新日時を伝えます。
例
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
ETagと同様、キャッシュが有効かどうか判断するのに使います。
Expires
キャッシュの有効期限を日時で指定します。
例
Expires: Thu, 01 Dec 2024 16:00:00 GMT
この日時まではキャッシュを使ってOK、という意味。
ただし、Cache-Control
の max-age
の方が優先されます。
Vary
どの条件でキャッシュを使い分けるか指定します。
例
Vary: Accept-Encoding, User-Agent
圧縮形式やユーザーエージェントごとに、別のキャッシュを使うという意味です。
ヘッダーの確認方法
ブラウザの開発者ツール
最も簡単な確認方法です。
Chromeでの確認手順
- F12キーを押して開発者ツールを開く
- 「Network(ネットワーク)」タブをクリック
- ページを再読み込み
- 確認したいファイルをクリック
- 「Headers(ヘッダー)」タブに表示される
リクエストヘッダーとレスポンスヘッダーの両方が見られます。
curlコマンド
コマンドラインで確認する方法です。
基本的な使い方
curl -I https://www.example.com
-I
オプションで、ヘッダー情報だけを取得します。
詳細な情報を表示
curl -v https://www.example.com
-v
(verbose)オプションで、リクエストとレスポンスの両方を表示。
特定のヘッダーを追加
curl -H "User-Agent: MyBot/1.0" https://www.example.com
-H
オプションで、カスタムヘッダーを送れます。
オンラインツール
ブラウザ上で確認できるツールもあります。
HTTPヘッダーチェッカー
URLを入力するだけで、レスポンスヘッダーを確認できるWebサービス。
「http header checker」で検索すると、たくさん見つかります。
カスタムヘッダーの作成
Apacheでの設定
独自のヘッダーを追加できます。
mod_headersモジュールの有効化
sudo a2enmod headers
sudo systemctl restart apache2
ヘッダーの追加
Header set X-Custom-Header "My Value"
Header always set X-Content-Type-Options "nosniff"
.htaccess
ファイルや、サイト設定ファイルに記述します。
条件付きの設定
<FilesMatch "\.(html|php)$">
Header set Cache-Control "no-cache, no-store"
</FilesMatch>
HTMLとPHPファイルだけにヘッダーを追加する例です。
Nginxでの設定
Nginxでも同様に設定できます。
設定例
add_header X-Custom-Header "My Value";
add_header X-Content-Type-Options "nosniff" always;
always
を付けると、エラーレスポンスでも追加されます。
条件付きの設定
location ~* \.(html|php)$ {
add_header Cache-Control "no-cache, no-store";
}
PHPでの設定
プログラムから直接ヘッダーを送ることもできます。
基本的な書き方
<?php
header('Content-Type: application/json; charset=UTF-8');
header('X-Custom-Header: My Value');
echo json_encode(['status' => 'success']);
?>
注意点header()
関数は、出力する前に呼ぶ必要があります。HTMLを出力した後では使えません。
よくあるトラブルとその対処法
CORSエラー
「CORS policy」というエラーが出る場合。
問題
別ドメインからのアクセスがブロックされています。
解決方法
サーバー側で適切なヘッダーを追加します。
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
*
は全てのドメインを許可する設定。本番環境では、特定のドメインを指定する方が安全です。
キャッシュが効きすぎる
変更したのに古いページが表示される問題。
原因Cache-Control
の設定が長すぎます。
解決方法
開発中は、キャッシュを無効にしましょう。
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
本番環境では、適切な期間を設定してください。
ヘッダーが二重に送信される
同じヘッダーが複数回送られている問題。
原因
Apacheの設定ファイルと .htaccess
の両方で設定している場合など。
解決方法Header unset
で既存のヘッダーを削除してから追加します。
Header unset X-Powered-By
Header set Server "MyServer"
文字化けが起きる
文字コードの指定が間違っている可能性があります。
解決方法
正しい文字コードを指定しましょう。
AddDefaultCharset UTF-8
Header set Content-Type "text/html; charset=UTF-8"
パフォーマンス最適化のヘッダー
圧縮の有効化
データを圧縮して転送量を減らします。
Apache(mod_deflate)
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript
AddOutputFilterByType DEFLATE application/json application/xml
</IfModule>
レスポンスヘッダー
Content-Encoding: gzip
ブラウザは、このヘッダーを見て自動的に解凍します。
Keep-Alive
接続を再利用して、通信の高速化を図ります。
設定例
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
レスポンスヘッダー
Connection: keep-alive
Keep-Alive: timeout=5, max=100
1つの接続で複数のファイルを取得できるため、高速化につながります。
Early Hints(103ステータス)
リソースを早期に読み込み始める新しい機能です。
レスポンスヘッダー
Link: </style.css>; rel=preload; as=style
Link: </script.js>; rel=preload; as=script
ページ本体を送る前に、必要なリソースをブラウザに伝えます。
まとめ:HTTPヘッダーでWebを制御しよう
HTTPヘッダーについて、基礎から実践まで詳しく解説してきました。
この記事のポイント
- HTTPヘッダーはWebの通信で重要な付加情報
- リクエストヘッダーとレスポンスヘッダーがある
- Content-Type、Cache-Control など重要なヘッダーが多数
- セキュリティ対策にもヘッダーが活躍
- キャッシュ制御でパフォーマンス向上
- 開発者ツールやcurlで簡単に確認できる
ヘッダーは見えないところで働いていますが、Web開発では必須の知識です。
適切なヘッダーを設定すれば、セキュリティが向上し、パフォーマンスも改善します。
実践のヒント
- まずは開発者ツールでヘッダーを確認する習慣を
- セキュリティヘッダーは必ず設定する
- キャッシュ設定は環境に応じて調整
- トラブル時はヘッダーを疑ってみる
この知識を活かして、より安全で高速なWebサイトを作っていきましょう!
コメント