HTTP ヘッダー - HTTP

HTTP ヘッダー
=========

**HTTP ヘッダー**により、 HTTP リクエストやレスポンスでクライアントやサーバーが追加情報を渡すことができます。 HTTP ヘッダーは、大文字小文字を区別しないヘッダー名とそれに続くコロン (`:`)、 値で構成されます。値の前にあるホワイトスペースは無視されます。

私的な独自のヘッダーは、以前は `X-` 接頭辞を使用していましたが、この慣習は 2012 年 6 月の RFC 6648 で非推奨になりました。これは、標準外のフィールドが標準になったときに発生する不便さのためです。それ以外のヘッダーは IANA レジストリーに収録されており、その基になったものは RFC 4229 です。また IANA は新たに提案された HTTP ヘッダーのレジストリーも管理しています。

ヘッダーは、そのコンテキストに応じて分類できます。

* リクエストヘッダーは、読み込むリソースについての情報や、そのリソースをリクエストしているクライアントに関する詳細な情報を持ちます。
* レスポンスヘッダーは、レスポンスに関する追加情報、例えば場所や提供しているサーバーに関する情報を保持します。
* 表現ヘッダーは、リソースの本体に関する情報、例えば MIME タイプや適用されるエンコード／圧縮方式などについての情報を持ちます。
* ペイロードヘッダー (en-US)は、転送されるデータの表現から独立した情報、例えばコンテンツの長さや転送に使われるエンコード方式などを持ちます。

またヘッダーは、プロキシーサーバーがどのように扱うかに応じてグループ化されます。

* `Connection`
* `Keep-Alive`
* `Proxy-Authenticate`
* `Proxy-Authorization`
* `TE` (en-US)
* `Trailer` (en-US)
* `Transfer-Encoding`
* `Upgrade` (プロトコルのアップグレードの仕組み (en-US)も参照)

エンドツーエンドヘッダー

これらのヘッダーは、メッセージの最終的な宛先、すなわちリクエストならばサーバー、レスポンスならばクライアントに伝送し*なければなりません*。中間のプロキシーはヘッダーを変更せずに再伝送しなければならず、またキャッシュには保存しなければなりません。

ホップバイホップヘッダー

これらのヘッダーは単一のトランスポート層の接続にのみ意味を持ち、プロキシーが再転送したり、キャッシュを行ったりしては*いけません*。なお、 `Connection` ヘッダーを用いて設定する場合があるのはホップバイホップヘッダーのみです。

認証
--

`WWW-Authenticate`

リソースへアクセスに使用すべき認証方法を定義します。

`Authorization`

サーバーでユーザーエージェントを認証するための資格情報を持ちます。

`Proxy-Authenticate`

プロキシーサーバーの背後にあるリソースへアクセスできるようにするために使用すべき認証方法を定義します。

`Proxy-Authorization`

プロキシーサーバーでユーザーエージェントを認証するための資格情報を持ちます。

キャッシュ
-----

`Age`

オブジェクトがプロキシーのキャッシュに存在する時間を秒数で表します。

`Cache-Control`

リクエストおよびレスポンスで、キャッシュ機能に関するディレクティブです。

`Clear-Site-Data`

リクエストしているウェブサイトに関連付けられた閲覧用のデータ (クッキー、ストレージ、キャッシュなど) を消去します。

`Expires`

レスポンスが古くなると考えられる日時を表します。

`Pragma`

リクエストからレスポンスへの流れの中でさまざまな影響がある、実装依存のヘッダーです。 `Cache-Control` ヘッダーが未実装である HTTP/1.0 キャッシュとの後方互換性のために使用します。

`Warning`
非推奨

起こりうる問題に関する一般警告情報です。

クライアントヒント
---------

HTTP のクライアントヒントとは、端末の種類やネットワークの状態など、クライアントに関する有用な情報を提供する一連のリクエストヘッダーのことで、サーバーはこれらの条件に合わせて提供するコンテンツを最適化することができます。

サーバーは、 `Accept-CH` を使用して、クライアントが関心を持っているクライアントヒントヘッダーを積極的に要求します。クライアントは、要求されたヘッダーを後続のリクエストに含めることがあります。

`Accept-CH`
Experimental

サーバーはクライアントヒントに対応していることを、 `Accept-CH` ヘッダーフィールドまたは HTML の `<meta>` 要素の `http-equiv` 属性で同等の指定をすることで広報することができます。

`Accept-CH-Lifetime`
Experimental

非推奨

サーバーは、指定された期間サーバーが対応する一連のクライアントヒントを記憶するようクライアントに依頼し、そのサーバーのオリジンに対するその後のリクエストでクライアントヒントを配信できるようにすることができます。

`Critical-CH` (en-US)
Experimental

サーバーは `Accept-CH` と共に `Critical-CH` を使用し、受け入れられるクライアントヒントも重要なクライアントヒント であることを指定しています。

クライアントヒントの様々なカテゴリーを以下に示します。

### ユーザーエージェントクライアントヒント

ユーザーエージェントクライアントヒントは、ユーザーエージェント、それが動作しているプラットフォーム/アーキテクチャ、ユーザーエージェントやプラットフォーム上に設定されたユーザー環境設定に関する情報を提供するリクエストヘッダーです。

`Sec-CH-Prefers-Reduced-Motion` (en-US)
Experimental

ユーザーエージェントで動きの縮小を優先する設定。

`Sec-CH-UA` (en-US)
Experimental

ユーザーエージェントのブランド名とバージョン。

`Sec-CH-UA-Arch` (en-US)
Experimental

ユーザーエージェントの基盤となるプラットフォームアーキテクチャ。

`Sec-CH-UA-Bitness` (en-US)
Experimental

ユーザーエージェントの基本的な CPU アーキテクチャのビット数（例: "64" ビット）。

`Sec-CH-UA-Full-Version` (en-US)
非推奨

ユーザーエージェントの意味づけされた完全なバージョン文字列。

`Sec-CH-UA-Full-Version-List` (en-US)
Experimental

ユーザーエージェントのブランドリストにある各ブランドのフルバージョン。

`Sec-CH-UA-Mobile` (en-US)
Experimental

ユーザーエージェントがモバイル端末で動作している、あるいは、より一般的には、「モバイル」の使い勝手を好んでいる。

`Sec-CH-UA-Model` (en-US)
Experimental

ユーザーエージェントの端末モデル。

`Sec-CH-UA-Platform` (en-US)
Experimental

ユーザーエージェントの基盤となっているオペレーティングシステム/プラットフォーム。

`Sec-CH-UA-Platform-Version` (en-US)
Experimental

ユーザーエージェントの基盤となっているオペレーションシステムのバージョン。

### 端末クライアントヒント

`Content-DPR` (en-US)
非推奨

Experimental

画像リソースを選択するために `DPR` クライアントヒントが使用されたリクエストで、 画像デバイスとピクセルの比率を確認するために使用される *レスポンスヘッダー* です。

`Device-Memory`
非推奨

Experimental

技術的には端末メモリー API の一部で、このヘッダーはクライアントが持つおよその RAM の量を表します。

`DPR`
非推奨

Experimental

クライアントの端末ピクセル比 (DPR)、すなわち CSS ピクセルあたりの物理ピクセル数を示します。

`Viewport-Width` (en-US)
非推奨

Experimental

数値で、レイアウトビューポートの幅を CSS ピクセル数で示します。指定されたピクセル数は、それ以上の最小の整数に丸められます（つまり切り上げ）。

`Width` (en-US)
非推奨

Experimental

数値で、要求するリソースの幅（つまり画像の内在的な寸法）を物理ピクセル数で示します。

### ネットワーククライアントヒント

ネットワーククライアントヒントにより、サーバーはネットワークの帯域やレイテンシーに基づいて、どの情報を送るかを選択することができます。

`Downlink` (en-US)

サーバーに対するクライアントのコネクションのおよその帯域を、 Mbps で表します。これは Network Information API の一部です。

`ECT` (en-US)

有効接続種別 (「ネットワークプロファイル」) は、そのコネクションのレイテンシーや帯域に最も近いものです。これは Network Information API の一部です。

`RTT` (en-US)

アプリケーション層のラウンドトリップ時間 (RTT) をミリ秒で表し、これにはサーバーの処理時間も含みます。これは Network Information API の一部です。

`Save-Data` (en-US)
Experimental

論理型で、ユーザーエージェントのデータ利用の削減についての設定を示します。

条件付き
----

`Last-Modified`

リソースが最後に変更された日時であり、同じリソースの複数のバージョンを比較するために使用されます。 `ETag` より正確さは低いのですが、環境によっては計算が容易です。`If-Modified-Since` や `If-Unmodified-Since` を使用する条件付きリクエストでは、リクエストの動作を変更するためにこの値を使用します。

`ETag`

一意な文字列であり、リソースのバージョンを識別します。 `If-Match` や `If-None-Match` を使用する条件付きリクエストでは、リクエストの動作を変更するためにこの値を使用します。

`If-Match`

リクエストを条件付きにして、保存されたリソースが指定した ETag のいずれかに一致する場合に限りメソッドを適用します。

`If-None-Match`

リクエストを条件付きにして、保存されたリソースが指定した ETag のいずれかに一致*しない*場合に限りメソッドを適用します。これはキャッシュを更新する (安全なリクエスト向け)、あるいはすでにリソースが存在する場合に新しいリソースのアップロードを止めるために使用します。

`If-Modified-Since`

リクエストを条件付きにして、そのリソースが指定した日時より後に変更されている場合に限り転送するようリクエストします。キャッシュが期限切れである場合に限りデータを転送するために使用します。

`If-Unmodified-Since`

リクエストを条件付きにして、そのリソースが指定した日時より後に変更されていない場合に限り転送するようリクエストします。これは、特定の範囲の新しい断片と古い断片の一貫性を保証する、あるいは既存の文書を変更するときに楽観的な並行性制御システムを実装するために使用します。

`Vary`

新しいものを元のサーバーにリクエストするのではなく、キャッシュされたレスポンスが使用できるよう決定するために、リクエストヘッダーを一致させる方法を定めます。

接続管理
----

`Connection`

現在の転送が完了した後も、ネットワークコネクションを維持するかを制御します。

`Keep-Alive`

持続的なコネクションをどれだけの期間維持するかを制御します。

コンテンツネゴシエーション
-------------

コンテンツネゴシエーションヘッダーです。

`Accept`

送り返すことができるデータの種類をサーバーに通知します。

`Accept-Encoding`

送り返すリソースで使用できるエンコードアルゴリズム (一般的には圧縮アルゴリズム) をサーバーに通知します。

`Accept-Language`

送り返すリソースで期待する自然言語をサーバーに通知します。これはヒントであり、必ずしもユーザーの完全な制御下にあるものではありません。サーバーはユーザーの選択 (ドロップダウンリストで選ぶ言語など) を明示的に上書きしないように、常に注意を払うべきです。

制御
--

`Expect`

リクエストを適切に扱うためにサーバーが実行しなければならないと期待されていることを示します。

`Max-Forwards` (en-US)

`TRACE` を使用する場合、リクエストが送信者に反映されるまでにできる最大のホップ数を示します。

クッキー
----

`Cookie`

過去に `Set-Cookie` ヘッダーでサーバーから送信されて保存している HTTP クッキーを持ちます。

`Set-Cookie`

サーバーからユーザーエージェントにクッキーを送信します。

CORS
----

*CORS についての詳細は、こちらを参照してください。*

`Access-Control-Allow-Origin`

レスポンスが共有可能かを示します。

`Access-Control-Allow-Credentials`

credentials フラグが真であるときに、リクエストへのレスポンスを開示してよいかを示します。

`Access-Control-Allow-Headers`

プリフライトリクエストへのレスポンスで使用し、実際のリクエストを行うときに使用できる HTTP ヘッダーを指定します。

`Access-Control-Allow-Methods`

プリフライトリクエストへのレスポンスで、リソースへアクセスするときに使用できるメソッドを指定します。

`Access-Control-Expose-Headers`

ヘッダー名を羅列して、レスポンスの一部として開示できるヘッダーを示します。

`Access-Control-Max-Age`

プリフライトリクエストの結果をキャッシュしてよい期間を示します。

`Access-Control-Request-Headers`

実際のリクエストを行う際に使用する HTTP ヘッダーをサーバーがわかるようにするため、プリフライトリクエストを発信する際に使用します。

`Access-Control-Request-Method`

実際のリクエストを行う際に使用する HTTP メソッドをサーバーがわかるようにするため、プリフライトリクエストを発信する際に使用します。

`Origin`

どこから読み込みが発生したかを示します。

`Timing-Allow-Origin`

Resource Timing API の機能を通じて受け取った属性の値を見ることができるオリジンを指定します。そうでなければオリジン間の制約によってゼロとして報告されます。

ダウンロード
------

`Content-Disposition`

転送したリソースをインラインで表示すべきか (ヘッダーが存在しない場合の既定の動作)、またはダウンロードとして扱い、「名前を付けて保存」ウィンドウを表示すべきかを示します。

メッセージ本文の情報
----------

`Content-Length`

リソースの大きさを、バイト単位の10進数で示します。

`Content-Type`

リソースのメディア種別を示します。

`Content-Encoding`

圧縮アルゴリズムを指定するために使用します。

`Content-Language`

読者向けに言語を示すヘッダーであり、ユーザーが自身の好む言語に応じて区別することができます。

`Content-Location`

返すデータの代替データの場所を示します。

プロキシー
-----

`Forwarded`

リクエストのパスにプロキシーが関与したときに変更または遺失した、プロキシーサーバーのクライアント側の情報を持ちます。

`X-Forwarded-For`
Non-standard

HTTP プロキシーやロードバランサーを経由してウェブサーバーに接続するクライアントの、接続元 IP アドレスを識別します。

`X-Forwarded-Host`
Non-standard

プロキシーやロードバランサーに接続するクライアントがリクエストした、オリジナルのホストを示します。

`X-Forwarded-Proto`
Non-standard

クライアントがプロキシーやロードバランサーに接続するために使用したプロトコル (HTTP または HTTPS) を識別します。

`Via`

フォワードプロキシーとリバースプロキシーの両方が追加するヘッダーであり、リクエストヘッダーとレスポンスヘッダーのどちらでも見られます。

リダイレクト
------

`Location`

ページのリダイレクト先の URL を示します。

`Refresh`

ブラウザーにページを再読み込みするか、別のページにリダイレクトするように指示します。 `http-equiv="refresh"` を持つ `meta` 要素と同じ値をとります。

リクエストコンテキスト
-----------

`From`

リクエストを行うユーザーエージェントを操作している人間の、インターネット電子メールアドレスを持ちます。

`Host`

サーバーのドメイン名 (バーチャルホスト向け) およびサーバーが待ち受けている TCP ポート番号 (省略可能) を指定します。

`Referer`

現在リクエストしているページへリンクしていた、前のウェブページのアドレスです。

`Referrer-Policy`

`Referer` ヘッダーで送信するどのリファラー情報をリクエストに含めるかを制御します。

`User-Agent`

リクエストを行うユーザーエージェントソフトウェアのアプリケーションタイプ、オペレーティングシステム、ベンダー、バージョンを、ネットワークプロトコルのピアが識別できるようにする文字列を持ちます。 Firefox ユーザーエージェント文字列リファレンスもご覧ください。

レスポンスコンテキスト
-----------

`Allow`

リソースがサポートする HTTP リクエストメソッドを示します。

`Server`

リクエストを扱うサーバーが使用するソフトウェアの情報を持ちます。

範囲付きリクエスト
---------

`Accept-Ranges`

サーバーが範囲付きリクエストに対応するかどうか、対応していれば対応する場合は、範囲を表すことができる単位を示します。

`Range`

サーバーが返すべきである文書の範囲を示します。

`If-Range`

指定した ETag または日時がリモートのリソースにマッチする場合に限定した、条件付き range request を生成します。異なるバージョンのリソースから 2 つの範囲をダウンロードすることを防ぎます。

`Content-Range`

部分的なメッセージが、メッセージ本文全体のどこに位置するかを示します。

セキュリティ
------

`Cross-Origin-Embedder-Policy` (COEP)

サーバーが指定された文書の埋め込み方針を宣言するために使います。

`Cross-Origin-Opener-Policy` (COOP)

他のドメインがウィンドウを開いたり制御したりすることを防ぎます。

`Cross-Origin-Resource-Policy` (CORP)

このヘッダーが適用されたリソースのレスポンスが他のドメインから読み取られるのを防ぎます。

`Content-Security-Policy` (CSP)

ユーザーエージェントがページで読み込むことを許可するリソースを制御します。

`Content-Security-Policy-Report-Only`

ウェブの開発者がポリシーの効果を適用せずに監視することで、実験を行うことができます。これらの違反レポートは、 HTTP `POST` リクエストによって指定した URI へ送信される JSON 文書で構成されます。

`Expect-CT`

サイトが証明書の透明性要件の報告や実施を選択できるようにします。これにより、そのサイトで不正な証明書の使用に気づかないことを防ぎます。サイトが Expect-CT ヘッダーを有効にした場合、そのサイトの証明書が公開CTログに表示されることを Chrome が確認するようにリクエストしています。

`Origin-Isolation`
Experimental

ウェブアプリケーションをオリジンから独立させるための仕組みを提供します。

`Permissions-Policy`

自身のフレームまたはその中に埋め込まれた `<iframe>` で、ブラウザーの機能を使用することを許可または拒否する仕組みを提供します。

`Strict-Transport-Security` (HSTS)

HTTP の代わりに HTTPS による通信を強制します。

`Upgrade-Insecure-Requests`

暗号化や認証されたレスポンスについて、クライアントの設定を表す信号をサーバーに送信して、`upgrade-insecure-requests` ディレクティブを正しく扱うことができます。

`X-Content-Type-Options`

ブラウザーで MIME スニッフィングを無効化して、`Content-Type` で指定したタイプを強制的に使用させます。

`X-Download-Options`

HTTP の `X-Download-Options` ヘッダーは、ブラウザー (Internet Explorer) がアプリケーションからのダウンロードでファイルを「開く」の選択肢を表示しないようにし、アプリケーションのコンテキストで実行するアクセス権を得ることがないようにして、ファイルとすることでフィッシング詐欺を防止します。

`X-Frame-Options` (XFO)

ブラウザーがページを `<frame>`, `<iframe>`, `<embed>`, `<object>` の内部に表示することを許可するかを示します。

`X-Permitted-Cross-Domain-Policies`

クロスドメインポリシーファイル (`crossdomain.xml`) を許可するかどうかを指定します。このファイルは、 Adobe の Flash Player、Adobe Acrobat、Microsoft Silverlight、Apache Flex などのクライアントに、同一オリジンポリシーによって制限されているドメイン間のデータを処理する許可を与えるポリシーを定義することができます。詳細については、 Cross-domain Policy File Specification を参照してください。

`X-Powered-By`

ホスティング環境やその他のフレームワークによって設定される可能性があり、アプリケーションや訪問者に有益ではない情報を含みます。潜在的な脆弱性が発現することを防ぐために、このヘッダーは設定しないでください。

`X-XSS-Protection`

クロスサイトスクリプティングのフィルタリングを有効化します。

メタデータ読み取りリクエストヘッダー
------------------

メタデータ読み取りリクエストヘッダーは、リクエストが発生したときのコンテキストに関する情報を提供します。これによりサーバーは、リクエストがどこから来たのか、リソースがどのように使用されるのかに基づいて、リクエストを許可すべきかどうかを判断することができます。

`Sec-Fetch-Site` (en-US)

リクエスト開始元のオリジンと宛先のオリジンとの関係を示すリクエストヘッダーです。これは構造化ヘッダーで、値はトークンであり、取りうる値は `cross-site`, `same-origin`, `same-site`, `none` です。

`Sec-Fetch-Mode` (en-US)

サーバーへのリクエストモードを示すリクエストヘッダーです。これは構造化ヘッダーで、値はトークンであり、取りうる値は `cors`, `navigate`, `nested-navigate`, `no-cors`, `same-origin`, `websocket` です。

`Sec-Fetch-User`

ナビゲーションリクエストがユーザー操作によって起動されたかどうかを示すリクエストヘッダーです。これは構造化ヘッダーであり、論理値で、取りうる値は `?0` ならば偽、 `?1` ならば真です。

`Sec-Fetch-Dest` (en-US)

リクエストの宛先を示すリクエストヘッダーです。これは構造化ヘッダーで、値はトークンであり、取りうる値は `audio`, `audioworklet`, `document`, `embed`, `empty`, `font`, `image`, `manifest`, `object`, `paintworklet`, `report`, `script`, `serviceworker`, `sharedworker`, `style`, `track`, `video`, `worker`, `xslt` です。

`Service-Worker-Navigation-Preload` (en-US)

 サービスワーカーの起動中に、リソースに対して `fetch()` で先制的なリクエストをする際に送られるリクエストヘッダーです。
 この値は `NavigationPreloadManager.setHeaderValue()` (en-US) で設定され、通常の `fetch()` 処理とは異なる形でリソースを返すべきことをサーバーに通知するために使用することができます。

サーバー送信イベント
----------

`Last-Event-ID`

TBD

`NEL`
Experimental

開発者がネットワークエラー報告ポリシーを宣言できるようにする仕組みを定義します。

`Ping-From`

TBD

`Ping-To`

TBD

`Report-To`

警告やエラーを送信るためのブラウザーに対するサーバーのエンドポイントを指定するために使用します。

転送エンコーディング
----------

`Transfer-Encoding`

エンティティをユーザーへ問題なく転送できるエンコード形式を指定します。

`TE` (en-US)

ユーザーエージェントが進んで受け入れる転送エンコーディングを指定します。

`Trailer` (en-US)

送信者が chunk メッセージの終端に追加フィールドを含めることができます。

WebSocket
---------

`Sec-WebSocket-Key`

TBD

`Sec-WebSocket-Extensions`

TBD

`Sec-WebSocket-Accept` (en-US)

TBD

`Sec-WebSocket-Protocol`

TBD

`Sec-WebSocket-Version`

TBD

その他
---

`Accept-Push-Policy`
Experimental

クライアントはリクエストに対して求めるプッシュポリシーを、リクエスト内で `Accept-Push-Policy` ヘッダーフィールドを送信することで表現することができます。

`Accept-Signature`
Experimental

クライアントは `Accept-Signature` ヘッダーフィールドを送信して、利用可能な署名を利用する意図を示したり、対応している署名の種類を示したりすることができます。

`Alt-Svc`

このサービスにたどり着く他の方法のリストに使用します。

`Date`

メッセージが生成された日時です。

`Early-Data`
Experimental

このリクエストが TLS early data で送信されたことを示します。

`Large-Allocation` (en-US)
非推奨

読み込み中のページは大量の割り当てが必要であることをブラウザーに伝えます。

`Link`

`Link` エンティティヘッダーフィールドは、 HTTP ヘッダー内の 1 つ以上のリンクを記述する方法を提供します。意味的には HTML の `<link>` 要素と等価です。

`Push-Policy`
Experimental

`Push-Policy`はリクエストを処理するときのプッシュ通知に関するサーバーの動作を定義します。

`Retry-After`

後続のリクエストを行う前に、ユーザーエージェントがどれだけの期間待つべきかを示します。

`Signature`
Experimental

`Signature` ヘッダーフィールドは、交換のための署名のリストを伝え、それぞれはその署名の権威を決定して、そして更新する方法についての情報を伴います。

`Signed-Headers`
Experimental

`Signed-Headers` ヘッダーフィールドは、シグネチャに含めるためのレスポンスヘッダーフィールドの順序付きリストを識別します。

`Server-Timing`

指定されたリクエストとレスポンスのサイクルについて、１つ以上のメトリクスまたは説明を通信します。

`Service-Worker-Allowed`

パス制約を解除するために、サービスワーカースクリプトのレスポンスで使用します。

`SourceMap`

生成されたコードとソースマップを関連付けます。

`Upgrade`

Upgrade ヘッダーフィールドに関連する RFC 文書は RFC 9110, section 7.8 です。標準仕様では、現在のクライアント、サーバー、トランスポート層プロトコル接続で別のプロトコルへ更新または変更するための規則を定めています。例えば、このヘッダー標準ではサーバーが Upgrade ヘッダーフィールドを認めて実装すると決める前提で、クライアントが HTTP 1.1 から WebSocket へ変更することを可能にします。どちらの相手も、 Upgrade ヘッダーフィールドで指定された要件を受け入れる必要はありません。これはクライアントのヘッダーでもサーバーのヘッダーでも使用できます。Upgrade ヘッダーフィールドを指定した場合は、更新オプションを指ヘッダーonnection ヘッダーフィールドも送信者が送信しなければなりません。Connection ヘッダーフィールドについて、詳しくは前述の RFC のセクション 7.6.1 をご覧ください。

`X-DNS-Prefetch-Control`

ユーザーがたどるであろうリンクや、ドキュメントが参照する画像、 CSS、 JavaScript などのリソースのドメイン名解決をブラウザーが事前に行う機能である、 DNS プリフェッチを制御します。

`X-Firefox-Spdy`
非推奨

Non-standard

TBD

`X-Pingback`
Non-standard

TBD

`X-Requested-With`

TBD

`X-Robots-Tag`
Non-standard

`X-Robots-Tag` ヘッダーは、一般の検索エンジンの結果でウェブページをどのように索引付けをするかを示します。このヘッダーは `<meta name="robots" content="…">` と等価です。

`X-UA-Compatible`
Non-standard

使用する文書モードを示すために Internet Explorer で使用されています。

協力
--

新しい記事を書いたり、既存のものを改善したりすることにご協力ください。

関連情報
----

* Wikipedia の HTTP ヘッダーの一覧のページ
* IANA レジストリー
* HTTP Working Group


HTTP の圧縮 - HTTP

HTTP の圧縮
========

**圧縮**は、ウェブサイトのパフォーマンスを向上させるための重要な手段です。文書によっては、必要な帯域を最大 70% 削減するほどサイズが縮減します。長年かけてアルゴリズムはより効率的になり、またクライアントおよびサーバーが新たなアルゴリズムに対応してきました。

実際のところ、圧縮の仕組みはブラウザーやサーバーがすでに実装していますので、ウェブ開発者が実装する必要性はありません。しかし、サーバーが適切に設定されるように注意しなければなりません。圧縮は、3 種類の異なるレベルで実施します。

* 始めに、一部のファイル形式は、固有の最適化された方法で圧縮されます。
* そして、一般的な暗号化が HTTP レベルで行われれる場合があります（リソースはエンドツーエンドで圧縮されて転送されます）
* 最後に HTTP コネクションの 2 つのノード間で、コネクションレベルで圧縮が定義される場合があります。
ファイル形式の圧縮
---------

それぞれのデータ形式には、無駄なスペース (*wasted space*) と呼ばれる冗長な領域が内部にあります。テキストは一般的に 60% もの冗長性を持つものであり、この割合は音声や動画といった他のメディアよりはるかに高くなります。テキストとは異なり、これらのその他のメディア形式はデータを格納するためにより多くの領域を使用するので、ストレージを最適化し領域を取り戻す必要性はごく初期に明らかになりました。技術者は特定の用途向けに設計されたファイル形式で使用される、最適化された圧縮アルゴリズムを設計しました。メディアファイルで使用される圧縮アルゴリズムは、大きく 2 つのカテゴリーに分類できます。

* *可逆圧縮*。圧縮・展開のサイクルで取り出したデータが変化しません。これは元のデータに（バイト単位で）一致します。
 画像では `gif` や `png` が可逆圧縮を使用しています。
* *非可逆圧縮*。圧縮・展開のサイクルにおいて、ユーザーが（できるだけ）認知できない方法で元のデータを変更します。
 ウェブ上の動画形式は非可逆です。 `jpeg` 画像も非可逆です。

`webp` のように可逆圧縮と非可逆圧縮のいずれかを使用できる形式もありますが、通常は非可逆圧縮で高圧縮・低圧縮を設定でき、当然ながらそれは品質の高低に結びつきます。サイトのパフォーマンスを高めるには、満足できる品質レベルを維持しながら、できるだけ圧縮することが理想です。画像の場合は、ツールが生成する画像はウェブ向けに十分最適化されていない場合があります。要求する品質で可能な限り圧縮するツールを使用することをお勧めします。この用途に特化した多くのツールがあります。

非可逆圧縮アルゴリズムは一般的に、可逆圧縮より効率がよくなります。

**メモ:** 特定の種類のファイルは圧縮が良好に機能しているため、通常は 2 度目の圧縮を行いません。実際のところ、大きなファイルの圧縮によって得られる追加の利益よりもオーバーヘッド (アルゴリズムは一般的に、初期のサイズに追加する辞書が必要です) のコストが上回る場合があります。圧縮済み形式のファイルで、以下の 2 つの技術は使用しないでください。

エンドツーエンドの圧縮
-----------

エンドツーエンドの圧縮は、ウェブサイトのパフォーマンスをもっとも向上させます。エンドツーエンドの圧縮は、サーバーによって行われるメッセージ本体の圧縮を指しており、圧縮されたデータはクライアントに到達するまで変更されません。中間のノードはすべて、本体部分に手をつけないままにします。

![圧縮された HTTP 本体をネットワークノード経由でクライアントに送信するサーバー。本体がクライアントにリーチするまで、ネットワーク上のどのホップでも展開されません。](/ja/docs/Web/HTTP/Compression/httpenco1.png)

現代のすべてのブラウザーやサーバーはこの圧縮をサポートしており、唯一取り決めることは、使用する圧縮アルゴリズムです。これらのアルゴリズムは、テキストに最適化されています。1990 年代に圧縮技術は速いペースで進歩して、いくつものアルゴリズムが、使用可能な選択肢に追加されました。現在妥当なアルゴリズムは、もっとも一般的な `gzip` と新たな挑戦者である `br` の 2 つだけです。

使用するアルゴリズムを選択するには、ブラウザーとサーバーでプロアクティブなコンテンツネゴシエーションを行います。ブラウザーは `Accept-Encoding` ヘッダーで、サポートするアルゴリズムを優先度順に並べて送信します。サーバーはそのうちひとつを選択して、レスポンスの本体の圧縮に使用します。そして `Content-Encoding` ヘッダーを使用して、選択したアルゴリズムをブラウザーに伝えます。エンコーディングに基づいて表現を選択するためにコンテンツネゴシエーションを使用したとき、少なくとも `Content-Encoding` を含めた `Vary` ヘッダーを、レスポンスとともに送信しなければなりません。この方法によって、リソースのさまざまな表現をキャッシュすることができます。

!['Accept-Encoding: br, gzip' ヘッダーでコンテンツをリクエストされたクライアント。サーバは Brotli アルゴリズムで圧縮した本体と、必要な 'Content-Encoding' ヘッダーと 'Vary' ヘッダーでレスポンスします。](/ja/docs/Web/HTTP/Compression/httpcompression1.png)

圧縮によってパフォーマンスが大きく向上しますので、画像・音声・動画といったすでに圧縮されているものを除くすべてのファイルで圧縮を有効化することを推奨します。

Apache は圧縮や mod\_deflate をサポートします。 Nginx では ngx\_http\_gzip\_module、 IIS では `<httpCompression>` 要素があります。

ホップバイホップの圧縮
-----------

ホップバイホップの圧縮はエンドツーエンドの圧縮に似ています。しかし、サーバー内のリソースでは圧縮を行わずに特定の表現形式を生成して転送しますが、クライアントとサーバーの間のパス上にある任意の 2 つのノードの間でメッセージの本体が圧縮されるという根本的な違いがあります。連続した中間ノードの間のコネクションで、*異なる*圧縮が行われることがあります。

![非圧縮 HTTP 本体をネットワークノード経由でクライアントに送信するサーバー。本体はクライアントに到達する前に、'Transfer-Encoding' ヘッダーによってネットワーク上のノードで圧縮・展開されます。](/ja/docs/Web/HTTP/Compression/httpte1.png)

これを行うために、 HTTP ではエンドツーエンドの圧縮のコンテンツネゴシエーションに似ている仕組みを使用します。リクエストを転送するノードは `TE` (en-US) ヘッダーを使用して圧縮アルゴリズムを伝えます。相手のノードは適切な方式を選択して圧縮を行い、 `Transfer-Encoding` ヘッダーを使用して、選択した方式を示します。

![クライアントが、圧縮関連のヘッダーを持たないコンテンツをサーバーにリクエストされた場合。サーバーは圧縮されていない本体で応答します。本体がクライアントにリーチするまでに、ネットワーク上のノードで圧縮と展開が行われます。](/ja/docs/Web/HTTP/Compression/httpcomp2.png)

実際は、ホップバイホップの圧縮はサーバーやクライアントにとって透過的であり、あまり使用されません。 `TE` (en-US) および `Transfer-Encoding` は主にチャンク形式でレスポンスを送信するために使用され、長さがわからないリソースの転送を開始することができます。

ホップレベルで圧縮や `Transfer-Encoding` を使用することは Apache、Nginx、IIS などほとんどのサーバーでまれであり、簡単に設定する方法はありません。このような設定は、主にプロキシーレベルで行います。


リソースと URI - HTTP

リソースと URI
=========

HTTP により、ブラウザーやその他のユーザーエージェントは、インターネット上の様々な*リソース*と通信することができます。このために、ブラウザーはリソースの*識別*および*場所*の両方が必要です。これら二つの情報が URI によって記述されます。

ウェブ上のリソースの識別

URI およびウェブ上のリソースへのアクセス方法です。

データ URI

特定の種類の URI である、識別子の中にリソース自体を埋め込んだデータ URI です。

www および www 以外の URL の選択

www の接頭辞が付いたドメインを使用するかどうかのアドバイスで、この記事では選択の結果がどうなるかと、どうするかを説明します。

MIME タイプ

MIME メディアタイプは、特定のリソースがどの種類の文書であるかを定義します。この記事は構文と、ウェブでよく使われる MIME タイプを紹介します。

よくある MIME タイプ

ウェブ開発者に便利なよくある MIME タイプの一覧です。

リソースの識別子と位置の分離: Alt-Svc ヘッダー

識別子と位置の両方が URL で記述されていますが、この 2 つは異なる概念であり、時には区別したほうが便利です。この記事では `Alt-Svc` ヘッダーを紹介します。


オリジン間リソース共有 (CORS) - HTTP

オリジン間リソース共有 (CORS)
==================

オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。

オリジン間リクエストとは、例えば `https://domain-a.com` で提供されているウェブアプリケーションのフロントエンド JavaScript コードが `XMLHttpRequest` を使用して `https://domain-b.com/data.json` へリクエストを行うような場合です。

セキュリティ上の理由から、ブラウザーは、スクリプトによって開始されるオリジン間 HTTP リクエストを制限しています。例えば、 `XMLHttpRequest`や Fetch API は同一オリジンポリシー (same-origin policy) に従います。つまり、これらの API を使用するウェブアプリケーションは、そのアプリケーションが読み込まれたのと同じオリジンに対してのみリソースのリクエストを行うことができ、それ以外のオリジンからの場合は正しい CORS ヘッダーを含んでいることが必要です。

![CORS の仕組みの図式化](/ja/docs/Web/HTTP/CORS/cors_principle.png)

CORS の仕組みは、安全なオリジン間のリクエストとブラウザー・サーバー間のデータ転送を支援します。最近のブラウザーは CORS を `XMLHttpRequest` や Fetch などの API で使用して、オリジン間 HTTP リクエストのリスクの緩和に役立てています。

CORS を使用したリクエストとは
-----------------

この cross-origin sharing standard では、以下についてオリジン間の HTTP リクエストができるようにしています。

* 前述のような `XMLHttpRequest` または Fetch API の呼び出し。
* ウェブフォント (CSS の `@font-face` で別ドメインのフォントを利用するため)。これによりサーバーは、許可したウェブサイトのみからオリジンをまたがって読み込んで利用できる TrueType フォントを提供することができます。
* WebGL テクスチャ。
* `drawImage()` を使用してキャンバスへ描かれた画像や映像のフレーム
* 画像から生成した CSS シェイプ。

この記事では、 HTTP ヘッダーの要件を含むオリジン間リソース共有の全般的な説明を行います。

機能概要
----

オリジン間リソース共有の仕様は、ウェブブラウザーから情報を読み取ることを許可されているオリジンをサーバーが記述することができる、新たな HTTP ヘッダーを追加することで作用します。加えて仕様書では、サーバーの情報に副作用を引き起こすことがある HTTP のリクエストメソッド (特に `GET` 以外の HTTP メソッドや、特定の MIME タイプを伴う `POST`) のために、ブラウザーが HTTP の `OPTIONS` リクエストメソッドを用いて、あらかじめリクエストの「プリフライト」 (サーバーから対応するメソッドの一覧を収集すること) を行い、サーバーの「認可」のもとに実際のリクエストを送信することを指示しています。サーバーはリクエスト時に「資格情報」 (Cookie や HTTP 認証など) を送信するべきかをクライアントに伝えることもできます。

CORS は様々なエラーで失敗することがありますが、セキュリティ上の理由から、エラーについて *JavaScript から知ることができない*よう定められています。コードからはエラーが発生したということしか分かりません。何が悪かったのかを具体的に知ることができる唯一の方法は、ブラウザーのコンソールで詳細を見ることです。

以降の節ではシナリオの説明に加え、 HTTP ヘッダーの使い方の詳細も提供します。

アクセス制御シナリオの例
------------

オリジン間リソース共有の動作の仕組みを説明する 3 つのシナリオを示します。これらの例はすべて `XMLHttpRequest` を用いており、対応しているブラウザーにおいて、オリジンをまたいでアクセスすることができます。

### 単純リクエスト

リクエストによっては CORS プリフライトを発生させません。これをこの記事では古い CORS 仕様書に倣って*単純リクエスト*と呼んでいますが、 (現在 CORS を定義している) Fetch 仕様書 ではこの用語を使用していません。

その動機は、HTML 4.0 からの `<form>` 要素（クロスサイト `XMLHttpRequest` と `fetch` に先行する）は、どのオリジンにでも単純なリクエストを送信できるので、サーバーを書く人はすでに cross-site request forgery (CSRF) から保護していなければならないからです。この仮定の下では、 CSRF の脅威はフォーム送信の脅威よりも悪くないので、サーバーはフォーム送信のように見えるすべてのリクエストを受け取ることを（プリフライトリクエストに応答することによって）オプトインする必要はないのです。しかし、サーバーは `Access-Control-Allow-Origin` を使用して、レスポンスをスクリプトと共有することを選択する必要があります。

*単純リクエスト*は、**以下のすべての条件を満たす**ものです。

* 許可されているメソッドのうちのいずれかであること。
    + `GET`
    + `HEAD`
    + `POST`
* ユーザーエージェントによって自動的に設定されたヘッダー (たとえば `Connection`、 `User-Agent`、 または Fetch 仕様書で*禁止ヘッダー名*として定義されているヘッダー)を除いて、手動で設定できるヘッダーは、 Fetch 仕様書で CORS セーフリストリクエストヘッダーとして定義されている以下のヘッダーだけです。
    + `Accept`
    + `Accept-Language`
    + `Content-Language`
    + `Content-Type` （但し、下記の追加の要件に注意してください）
    + `Range` （単純範囲ヘッダー値、例えば `bytes=256-` や `bytes=127-255` の場合）

**メモ:** Firefox は、まだ `Range` をセーフリストリクエストヘッダーとして実装していません。バグ 1733981を参照してください。

* `Content-Type` ヘッダーで指定できるメディア種別に許されるタイプ/サブタイプの組み合わせは、以下のもののみです。
    + `application/x-www-form-urlencoded`
    + `multipart/form-data`
    + `text/plain`
* `XMLHttpRequest` オブジェクトを使用してリクエストを行う場合は、 `XMLHttpRequest.upload` プロパティから返されるオブジェクトにイベントリスナーが登録されていないこと。すなわち、 `XMLHttpRequest` インスタンスを `xhr` とした場合、どのコードも `xhr.upload.addEventListener()` が呼び出してアップロードを監視するためのイベントリスナーを追加していないこと。
* リクエストに `ReadableStream` オブジェクトが使用されていないこと。

**メモ:** WebKit Nightly および Safari Technology Preview は、 `Accept`、`Accept-Language`、`Content-Language` ヘッダーの値に追加の制限を掛けています。これらのヘッダーが「標準外」の値の場合、 WebKit/Safari はそのリクエストが「単純リクエスト」の条件に合うとは判断しません。 WebKit/Safari がこれらのヘッダーのどの値を「標準外」と判断するかについては、以下の WebKit のバグを除いて文書化されていません。

* Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language
* Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS
* Switch to a blacklist model for restricted Accept headers in simple CORS requests

これは仕様の一部ではないので、他のブラウザーはこの追加の制限を実装していません。

例えば、ドメイン `https://foo.example` にあるウェブコンテンツがドメイン `https://bar.other` にあるコンテンツを呼び出したいとします。以下のようなコードが `foo.example` 内の JavaScript で使用されるかもしれません。

```js
const xhr = new XMLHttpRequest();
const url = "https://bar.other/resources/public-data/";

xhr.open("GET", url);
xhr.onreadystatechange = someHandler;
xhr.send();
```

この処理は、特権を扱うために CORS ヘッダーを使用して、クライアントとサーバーの間で簡単なデータ交換を行います。

![Diagram of simple CORS GET request](/ja/docs/Web/HTTP/CORS/simple-req.png)

この場合、ブラウザーがサーバーに何を送信し、サーバーが何を返すかを見てみましょう。

```http
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,\*/\*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
```

特筆すべきリクエストヘッダーは `Origin` であり、呼び出しが `https://foo.example` から来たことを表します。

サーバーがどのように返答するかを見てみましょう。

```http
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: \*
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[…XML データ…]
```

レスポンスでは、サーバーが `Access-Control-Allow-Origin` ヘッダーを `Access-Control-Allow-Origin: *` と返しており、そのリソースが**すべての**ドメインからアクセスできることを示しています。

```http
Access-Control-Allow-Origin: \*
```

`Origin` ヘッダーと `Access-Control-Allow-Origin` ヘッダーのこのパターンは、アクセス制御プロトコルのもっとも簡単な使い方です。 `https://bar.other` にあるリソースの所有者が、リソースへの制限を `https://foo.example` からのリクエスト*のみ*に制限したい (すなわち、 `https://foo.examle` 以外のドメインがオリジン間の作法でリソースにアクセスを許可しない) と考えていた場合は、以下のように送信します。

```http
Access-Control-Allow-Origin: https://foo.example
```

**メモ:** 資格情報を含むリクエストに応答する場合、サーバーは `Access-Control-Allow-Origin` ヘッダーにオリジンを値として指定する必要があり、"`*`" ワイルドカードを指定することはできません。

### プリフライトリクエスト

*単純リクエスト*とは異なり、「プリフライト」リクエストは始めに `OPTIONS` メソッドによる HTTP リクエストを他のドメインにあるリソースに向けて送り、実際のリクエストを送信しても安全かどうかを確かめます。オリジン間リクエストがユーザーデータに影響を与える可能性があるような場合に、プリフライトを行います。

プリフライトが行われるリクエストの例です。

```js
const xhr = new XMLHttpRequest();
xhr.open("POST", "https://bar.other/doc");
xhr.setRequestHeader("X-PINGOTHER", "pingpong");
xhr.setRequestHeader("Content-Type", "text/xml");
xhr.onreadystatechange = handler;
xhr.send("<person><name>Arun</name></person>");
```

上記の例では、 `POST` で送信する XML の本体を作成しています。また、標準外の `X-PINGOTHER` HTTP リクエストヘッダーを設定しています。このようなヘッダーは HTTP/1.1 プロトコルに含まれていませんが、ウェブアプリケーションでは一般的に便利なものです。リクエストで `Content-Type` に `text/xml` を使用しており、かつ独自のヘッダーを設定しているため、このリクエストではプリフライトを行います。

![プリフライトされたリクエストのイメージ図](/ja/docs/Web/HTTP/CORS/preflight_correct.png)

**メモ:** 後述するように、実際の `POST` リクエストでは `Access-Control-Request-*` ヘッダーを含みません。`OPTIONS` リクエストのみで必要になります。

クライアントとサーバーとの間のやりとりの全容を見てみましょう。最初のやり取りは*プリフライトリクエスト/レスポンス*です。

```http
OPTIONS /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,\*/\*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
```

上記の 1 - 10 行目は `OPTIONS` メソッドによるプリフライトリクエストを表します。ブラウザーは上記の JavaScript コードで使用していていたリクエストの引数に基づいて、プリフライトの送信が必要であることを判断します。これによりサーバーは実際のリクエストの引数によって送られるリクエストを受け入れ可能かを応答することができます。 OPTIONS は HTTP/1.1 のメソッドであり、サーバーから付加的な情報を得るために用いるもので、また安全なメソッド、つまりリソースを変更するためには使用できないメソッドです。 OPTIONS リクエストと合わせて、他にリクエストヘッダーを 2 つ送信していることに注意してください (それぞれ 9 行目と 10 行目です)。

```http
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
```

`Access-Control-Request-Method` ヘッダーは、プリフライトリクエストの一部として、実際のリクエストが `POST` リクエストメソッドで行われることをサーバーに通知します。 `Access-Control-Request-Headers` ヘッダーは、実際のリクエストにカスタムヘッダーである `X-PINGOTHER` および Content-Type が含まれることをサーバーに通知します。ここでサーバーは、この状況下でリクエストの受け入れを望むかを判断する機会が与えられます。

上記の 12 - 21 行目はサーバーが返すレスポンスであり、リクエストメソッド (`POST`) とリクエストヘッダー (`X-PINGOTHER`) が受け入れられることを示しています。特に、 15 - 18 行目を見てみましょう。

```http
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
```

サーバーは `Access-Control-Allow-Origin: https://foo.example` により、アクセスをリクエストしているオリジンのドメインだけに限定することを返答しています。また、 `Access-Control-Allow-Methods` を返しており、これは当該リソースへの問い合わせで `POST` および `GET` が有効なメソッドであることを伝えます（なお、このヘッダーはレスポンスヘッダーの `Allow` と似ていますが、アクセス制御でのみ使用されることに注意してください）。

またサーバーは、 `Access-Control-Allow-Headers` を "`X-PINGOTHER, Content-Type`" の値で送信し、実際のリクエストで使用されるヘッダーを承認しています。 `Access-Control-Allow-Methods` と同様に、 `Access-Control-Allow-Headers` は受け入れ可能なヘッダーをカンマ区切りのリストで表します。

最後に `Access-Control-Max-Age` は、プリフライトリクエストを再び送らなくてもいいように、プリフライトのレスポンスをキャッシュしてよい時間を秒数で与えます。既定値は 5 秒です。この例では 86400 秒、つまり 24 時間です。なお、ブラウザーはそれぞれ内部的な上限値を持っており、 `Access-Control-Max-Age` を超えた場合に制限を行います。

プリフライトリクエストが完了したら、実際のリクエストを送ります。

```http
POST /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,\*/\*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: https://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: https://foo.example
Pragma: no-cache
Cache-Control: no-cache

<person><name>Arun</name></person>

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some XML payload]
```

#### プリフライトリクエストとリダイレクト

現在のところ、すべてのブラウザーが下記のようなプリフライトリクエストのリダイレクトに対応しているわけではありません。プリフライトリクエストにリダイレクトが発生すると、ブラウザーによっては以下のようなエラーメッセージを報告します。

>
>
>  The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight.
>  Request requires preflight, which is disallowed to follow cross-origin redirects.
>
>
>
>

もともと CORS プロトコルはそのような動作を要求していましたが、その後で必要がないと変更されました。しかし、多くのブラウザーはまだ変更を実装していないため、もともと要求されていた動作に従っています。

ブラウザーが仕様に追いつくまで、以下の一方もしくは両方を行うことでこの制限を回避することができます。

* サーバー側の振る舞いを変更して、プリフライトが発生しないようにするか、リダイレクトが発生しないようにする
* リクエストをプリフライトを起こさない単純リクエストなどに変更する

これらの変更ができない場合は、次のような別な方法があります。

1. 単純リクエストを行い (Fetch API の `Response.url` または `XMLHttpRequest.responseURL` を使用する)、実際のプリフライトリクエストが転送される先を特定する。
2. 最初のステップの `Response.url` または `XMLHttpRequest.responseURL` で得た URL を使用して、もう一つのリクエスト (*本当の*リクエスト) を行う。

ただし、リクエストに `Authorization` ヘッダーが存在するためにプリフライトが発生するリクエストの場合、上記の手順を使用して制限を回避することはできません。リクエストが行われているサーバーを制御できない限り、まったく回避することはできません。

### 資格情報を含むリクエスト

**メモ:** 資格情報を含むリクエストを異なるドメインに行う場合、サードパーティクッキーポリシーも適用されます。このポリシーは、この章で説明しているように、サーバーやクライアントでの設定とは無関係に常に実施されます。

`XMLHttpRequest` や Fetch と CORS の両方によって明らかになる最も興味深い機能は、HTTP クッキーと HTTP 資格情報によってわかる「資格情報を含む」リクエストを作成することができることです。既定では、オリジン間の `XMLHttpRequest` または Fetch の呼び出しにおいて、ブラウザーは資格情報を送信**しません**。 `XMLHttpRequest` オブジェクトまたは `Request` のコンストラクターの呼び出し時に、特定のフラグを設定する必要があります。

以下の例では `https://foo.example` から読み込まれた元のコンテンツが、 `https://bar.other` にあるリソースに対してクッキーを設定したシンプルな GET リクエストを行います。 foo.example のコンテンツは以下のような JavaScript を含んでいるかもしれません。

```js
const invocation = new XMLHttpRequest();
const url = "https://bar.other/resources/credentialed-content/";

function callOtherDomain() {
  if (invocation) {
    invocation.open("GET", url, true);
    invocation.withCredentials = true;
    invocation.onreadystatechange = handler;
    invocation.send();
  }
}
```

7 行目で、クッキー付きで呼び出しを行うために `XMLHttpRequest` に設定する必要があるフラグ、 `withCredentials` という論理型の値を示しています。既定では、クッキーなしで呼び出しが行われます。これは単純な `GET` リクエストなのでプリフライトは行いませんが、ブラウザーは `Access-Control-Allow-Credentials``: true` ヘッダーを持たないレスポンスを**拒否**し、ウェブコンテンツを呼び出すレスポンスを作成**しない**でしょう。

![Access-Control-Allow-Credentials を使用した単純な GET リクエストの図。](/ja/docs/Web/HTTP/CORS/cred-req-updated.png)

以下はクライアントとサーバーとの間のやりとりの例です。

```http
GET /resources/credentialed-content/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,\*/\*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Referer: https://foo.example/examples/credential.html
Origin: https://foo.example
Cookie: pageAccess=2

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

[text/plain payload]
```

10 行目に `https://bar.other` 向けのクッキーが含まれていますが、bar.other が `Access-Control-Allow-Credentials``: true` (16 行目) をレスポンスに含めなければ、レスポンスは無視されこのウェブコンテンツで使用できません。

#### プリフライトリクエストと資格情報

CORS のプリフライトリクエストに資格情報を含めてはいけません。プリフライトリスクエストへの*レスポンス*には `Access-Control-Allow-Credentials: true` を指定して、実際のリクエストを資格情報付きで行うことができることを示す必要があります。

**メモ:** エンタープライズ認証サービスの中には、 Fetch 仕様書に反して、プリフライトリクエストで TLS クライアント証明書を送信することを要求するものがあります。

Firefox 87 では、`network.cors_preflight.allow_client_cert` を `true` に設定することで、この準拠していない動作を有効にすることができます。(Firefox バグ 1511151). Chromium ベースのブラウザーでは現在、CORS プリフライトリクエストで TLS クライアント証明書を常に送信します (Chrome bug 775438)。

#### 資格情報付きリクエストとワイルドカード

資格情報付きリクエストに返答する場合、

* サーバーは `Access-Control-Allow-Origin` ヘッダーで "`*`" ワイルドカードを指定**してはならず**、 `Access-Control-Allow-Origin: https://example.com` のように、明示的にオリジンを指定しなければなりません。
* サーバーは `Access-Control-Allow-Headers` ヘッダーで "`*`" ワイルドカードを指定**してはならず**、 `Access-Control-Allow-Headers: X-PINGOTHER, Content-Type` のように、明示的にヘッダー名を指定しなければなりません。
* サーバーは `Access-Control-Allow-Methods` ヘッダーで "`*`" ワイルドカードを指定**してはならず**、 `Access-Control-Allow-Methods: POST, GET` のように、明示的にメソッド名を指定しなければなりません。

リクエストが資格情報 (多くの場合は `Cookie` ヘッダー) を含んでおり、そのレスポンスが `Access-Control-Allow-Origin: *` ヘッダー (つまりワイルドカード) を含んでいる場合、ブラウザーはレスポンスへのアクセスをブロックし、開発ツールのコンソールに CORS エラーを報告します。

ただし、リクエストが (`Cookie` ヘッダーのような) 資格情報を含んで行われ、そのレスポンスがワイルドカードではない実際のオリジンを含んでいる場合 (例えば `Access-Control-Allow-Origin: https://example.com` など)、ブラウザーは指定されたオリジンからのレスポンスへのアクセスを許可します。

また、レスポンス内の `Access-Control-Allow-Origin` レスポンスヘッダーの値が実際のオリジンではなく "`*`" ワイルドカードであった場合、クッキーは設定されません。

#### サードパーティークッキー

CORS のレスポンスに設定されたクッキーは、サードパーティークッキーに関する通常のポリシーに従うことに注意してください。上記の例では、ページは `foo.example` から読み込まれていますが、 19 行目のクッキーは `bar.other` から送られているので、ユーザーのブラウザーがサードパーティークッキーをすべて拒否するよう設定されていた場合は保存されません。

リクエスト中のクッキー (10 行目) は、通常のサードパーティクッキーポリシーでも抑制されることがあります。したがって、クッキーポリシーが強制されていると、この章で説明されている機能が無効になり、事実上、認証されたリクエストを行うことができなくなるかもしれません。

SameSite (en-US) 属性に関するクッキーポリシーは適用されます。

HTTP レスポンスヘッダー
--------------

この節では、オリジン間リソース共有の仕様書で定義されている、アクセス制御のためにサーバーが返す HTTP レスポンスヘッダーを掲載します。前の章では、これらの実際の動作の概要を説明しました。

### Access-Control-Allow-Origin

返却されるリソースには、以下のような構文で 1 つの `Access-Control-Allow-Origin` ヘッダーがつくことがあります。

```http
Access-Control-Allow-Origin: <origin> | \*
```

`Access-Control-Allow-Origin` は、リソースへのアクセスを許可するオリジンをブラウザーに伝えるための単一のオリジン、または — 資格情報を**含まない**リクエストにおいては — どのオリジンにもリソースへのアクセスを許可することをブラウザーに伝えるワイルドカード "`*`" のどちらかを指定することができます。

例えば、 `https://mozilla.org` のオリジンからのコードにリソースへのアクセスを許可するには、次のように指定します。

```http
Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin
```

サーバーがワイルドカード "`*`" ではなく (ホワイトリストの一部としてリクエストするオリジンに基づいて動的に変更される可能性がある) 単一のオリジンを指定した場合は、サーバーは `Origin` を `Vary` レスポンスヘッダーに含めて、サーバーのレスポンスが `Origin` リクエストヘッダーの値によって変化することもクライアントに示してください。

### Access-Control-Expose-Headers

`Access-Control-Expose-Headers` ヘッダーは、指定されたヘッダーをブラウザー内の JavaScript (`getResponseHeader()` など) からアクセスできる許可リストに加えます。

```http
Access-Control-Expose-Headers: <header-name>[, <header-name>]\*
```

例えば、以下のようになります。

```http
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
```

これは、ブラウザーに対して `X-My-Custom-Header` および `X-Another-Custom-Header` ヘッダーを許可します。

### Access-Control-Max-Age

このヘッダーはプリフライトリクエストの結果をキャッシュしてよい時間を示します。プリフライトリクエストの例は、前出の例をご覧ください。

```http
Access-Control-Max-Age: <delta-seconds>
```

`delta-seconds` 引数は、結果をキャッシュしてよい時間を秒単位で示します。

### Access-Control-Allow-Credentials

`Access-Control-Allow-Credentials` は `credentials` フラグが true である場合に、リクエストへのレスポンスを開示してよいか否かを示します。プリフライトリクエストのレスポンスの一部として用いられたときは、実際のリクエストで資格情報を使用してよいか否かを示します。単純な `GET` リクエストはプリフライトを行いませんので、リソースへのリクエストが資格情報付きで行われた場合にリソースと共にこのヘッダーを返さなければ、ブラウザーがそのレスポンスを無視し、ウェブのコンテンツが返されないことに注意してください。

```http
Access-Control-Allow-Credentials: true
```

資格情報付きリクエストは前に説明したとおりです。

### Access-Control-Allow-Methods

`Access-Control-Allow-Methods` ヘッダーは、リソースへのアクセス時に許可するメソッドを指定します。これはプリフライトリクエストのレスポンスで用いられます。リクエストのプリフライトを行う条件については前述のとおりです。

```http
Access-Control-Allow-Methods: <method>[, <method>]\*
```

ブラウザーにこのヘッダーを送信する例を含む、プリフライトリクエストの例は前述のとおりです。

### Access-Control-Allow-Headers

`Access-Control-Allow-Headers` ヘッダーはプリフライトリクエストへのレスポンスで使用され、実際のリクエストを行う際に使用される HTTP ヘッダーを示します。このヘッダーはブラウザーの `Access-Control-Request-Headers` ヘッダーに対するサーバー側のレスポンスです。

```http
Access-Control-Allow-Headers: <header-name>[, <header-name>]\*
```

HTTP リクエストヘッダー
--------------

この節では、 HTTP リクエストを発行する際、オリジン間リソース共有機能を利用するためにクライアントが使用できるヘッダーの一覧を掲載します。なお、これらのヘッダーはサーバーの呼び出し時に設定されます。オリジン間 `XMLHttpRequest` の機能を使用する開発者は、オリジン間リソース共有のリクエストヘッダーをプログラムで設定する必要はありません。

### Origin

`Origin` ヘッダーはオリジン間のアクセスリクエストやプリフライトリクエストのオリジンを示します。

```http
Origin: <origin>
```

origin は、リクエストを開始したサーバーを示す URL です。ここにパス情報は含めず、サーバー名だけにします。

**メモ:** `origin` の値は `null` にすることができます。

なお、すべてのアクセス制御リクエストにおいて、 `Origin` ヘッダーは**常に**送信されます。

### Access-Control-Request-Method

`Access-Control-Request-Method` はプリフライトリクエストを発信する際に、実際のリクエストを行う際に使用する HTTP メソッドをサーバーに知らせるために使用します。

```http
Access-Control-Request-Method: <method>
```

使用例は前述のとおりです。

### Access-Control-Request-Headers

`Access-Control-Request-Headers` ヘッダーは、プリフライトリクエストを発行する際に、実際のリクエストを行う際に (`setRequestHeader()` などによって) 使用する HTTP ヘッダーをサーバーに知らせるために使用します。このブラウザー側のヘッダーは、サーバー側のヘッダー `Access-Control-Allow-Headers` によって回答されます。
```

Access-Control-Request-Headers: <field-name>[, <field-name>]*
```

使用例は前述のとおりです。

仕様書
---

| Specification |
| --- |
| Fetch Standard # http-access-control-allow-origin |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* CORS のエラー
* Enable CORS: I want to add CORS support to my server
* `XMLHttpRequest`
* Fetch API
* Will it CORS? - 対話型の CORS の説明および生成
* How to run Chrome browser without CORS
* Using CORS with All (Modern) Browsers
* Stack Overflow のよくある問題を解決するための "how to" 情報:
    + CORS のプリフライトを防止する方法
    + CORS プロキシーを使用して「Access-Control-Allow-Origin ヘッダーの欠落」を回避する方法
    + 「Access-Control-Allow-Origin ヘッダーがワイルドカードを扱えない」ことを修正する方法


HTTP のリダイレクト - HTTP

HTTP のリダイレクト
============

**URL リダイレクト**は、 *URL 転送*とも呼ばれ、ページ、フォーム、ウェブサイト全体、ウェブアプリケーションなどに 2 つ以上の URL のアドレスを与える技術です。 HTTP ではこの操作のために、特別な種類のレスポンスである ***HTTP リダイレクト***を提供しています。

リダイレクトには多くの目的があります。

* サイトをメンテナンスしている間の一時的なリダイレクト
* サイトの構成を変更した後も外部のリンクを機能させるための恒久的なリダイレクト、ファイルをアップロードしているときの進捗を示すページなど
原理
--

HTTP では、リダイレクトはリクエストに対して、サーバーが特別な*リダイレクト*レスポンスを送信することによって、サーバーがリダイレクトを発生させます。リダイレクトレスポンスはステータスコードが `3` で始まり、 `Location` ヘッダーがリダイレクト先の URL を保持しています。

ブラウザーがリダイレクトを受け取ると、 `Location` ヘッダーで提供された新たな URL を使用して直ちに読み込みを行います。追加の往復によるパフォーマンスの低下の他に、ユーザーがリダイレクトに気づくことはほとんどありません。

![最初のリクエストはクライアントからサーバーに送られます。サーバーはリダイレクト先のURLとともに 301:moved permanently で応答します。クライアントは新しい URL への GET リクエストを行い、サーバーは 200 OK レスポンスでこれを返します。](/ja/docs/Web/HTTP/Redirections/httpredirect.png)

リダイレクトには何種類かがありますが、3 つのカテゴリーに分類することができます。

1. 恒久的リダイレクト
2. 一時的リダイレクト
3. 特殊リダイレクト
### 恒久的リダイレクト

これらのリダイレクトは永遠に続くことを意味します。これらのリダイレクトは、元の URL はもう使用されず、新しいものに置き換えるべきであることを示しています。検索エンジンのロボット、 RSS リーダー、および他のクローラーは、リソースの元の URL を更新します。

| コード | テキスト | メソッドの扱い | 主な使用例 |
| --- | --- | --- | --- |
| `301` | `Moved Permanently` | `GET` メソッドは変更しません。 他のメソッドは `GET` に変更されるかもしれません。[1] | ウェブサイトの再編。 |
| `308` | `Permanent Redirect` | メソッドや本文は変更しません。 | GET 以外のリンクや操作を含むウェブサイトの再編。 |

[1] 仕様書ではメソッドの変更を意図していませんが、メソッドを変更するユーザーエージェントが存在します。 `308` が定義されたのは、 `GET` 以外のメソッドを使用するときの動作のあいまいさをなくすためです。

### 一時的リダイレクト

正規の場所でレスポンスしたリソースにアクセスすることはできませんが、別の場所でアクセスできる場合があります。このような場合に、一時的なリダイレクトを使用できます。

検索エンジンのロボットは、新たな一時的 URL を記録しません。一時的リダイレクトは、リソースを作成、更新、削除しているときに一時的な進捗ページを提供するためにも利用されます。

| コード | テキスト | メソッドの扱い | 主な使用例 |
| --- | --- | --- | --- |
| `302` | `Found` | `GET` メソッドは変更しません。 他のメソッドは `GET` に変更されるかもしれません。[2] | ウェブページは不測の理由により、一時的に利用できない状態です。 |
| `303` | `See Other` | `GET` メソッドは変更しません。 他のメソッドは `GET` に*変更します* (本文は失われます)。 | ページの再読み込みによって操作が再度実施されることを防ぐために、`PUT` や `POST` の後のリダイレクトで使用します。 |
| `307` | `Temporary Redirect` | メソッドと本文は変更しません。 | ウェブページは不測の理由により、一時的に使用できない状態です。検索エンジンは自身のリンクを更新しません。 `302` と比較して、サイトで `GET` 以外の操作を使用できる場合に推奨されます。 |

[2] 仕様書ではメソッドの変更を意図していませんが、実際はメソッドを変更するユーザーエージェントが存在します。`GET` 以外のメソッドを使用するときの動作のあいまいさをなくすために、 `307` が定義されました。

### 特殊リダイレクト

`304` (Not Modified) は、ページをローカルにキャッシュした（陳腐化した）複製へリダイレクトします。また `300` (Multiple Choice) は、手動リダイレクトです。ブラウザーがウェブページとして表示する本文には使用可能なリダイレクトのリストがあり、ユーザーはひとつ選択してクリックします。

| コード | テキスト | 主な使用例 |
| --- | --- | --- |
| `300` | `Multiple Choice` | 多くはありません。本文内の HTML ページに選択肢の一覧があります。 `Link` ヘッダーに `rel=alternate` がある場合は、機械可読な選択肢を提供することが推奨されます。 |
| `304` | `Not Modified` | 再検証された条件付きリクエストのために送信されます。キャッシュされたレスポンスがまだ新鮮で使用可能であることを示します。 |

リダイレクトを指定する代替手段
---------------

HTTP リダイレクトは、リダイレクトを定義する唯一の手段ではありません。他にも 2 つの方法があります。

1. `<meta>` 要素を使用する HTML リダイレクト
2. DOM による JavaScript リダイレクト
### HTML リダイレクト

HTTP リダイレクトはリダイレクトを作成するための最良の方法ですが、サーバーの制御権を持っていない場合もあります。このような場合は、そのページの `<head>` 内に `<meta>` 要素を記述し、その `http-equiv` 属性に `Refresh` を設定してみてください。ページを表示すると、ブラウザーは示されたページへ移動します。

```html
<head>
  <meta http-equiv="Refresh" content="0; URL=https://example.com/" />
</head>
```

`content` 属性は、指定した URL へリダイレクトする前にブラウザーが何秒待つべきかを示す値から始まります。アクセシビリティを高めるため、常に `0` を設定しましょう。

当然ながらこの方法は HTML でしか動作せず、画像などのコンテンツでは使用できません。

### JavaScript リダイレクト

JavaScript のリダイレクトは `window.location` プロパティに URL 文字列を設定することで実行され、新たなページが読み込まれます。

```js
window.location = "https://example.com/";
```

HTML リダイレクトと同様にすべてのリソースでは動作できず、また JavaScript を実行するクライアントでしか動作しないことは明らかです。一方、例えば特定の条件に一致した場合にのみリダイレクトを行うなど、さまざまな可能性があります。

### 優先順位

リダイレクトを起動する方法が 3 種類あり、同時に複数の方法を指定できますが、どのリダイレクトが最初に適用されるのでしょうか？

1. HTTP リダイレクトが常に最初に動作します。 — 転送されるページがない場合でも存在するからです。
2. HTTP リダイレクトが存在しなければ、HTML リダイレクト (`<meta>`) が動作します。
3. JavaScript リダイレクトが最後に、 JavaScript が有効であれば実行されます。

可能であれば常に HTTP リダイレクトを使用して、`<meta>` は追加しないようにしましょう。誰かが HTTP リダイレクトを変更して HTML リダイレクトを変更し忘れると、リダイレクトが同一ではなくなったり、無限ループになったり、その他の問題が発生したりします。

使用例
---

リダイレクトの使用例は多数ありますが、どのリダイレクトもパフォーマンスへの影響がありますので、使用は最小限にとどめるべきです。

### ドメインの別名

理想的なのは、ひとつのリソースに対してひとつの場所、そしてひとつの URL が存在することです。しかし、リソースに別名を設定する理由はいくつかあります。

サイトへの到達方法を拡大するため

よくある事例は、サイトが `www.example.com` ドメイン配下に存在しているとき、`example.com` からもアクセスできるようにしたい場合です。この場合は、`example.com` から `www.example.com` へのリダイレクトを設定します。また、一般的に使用される同義語や、ドメイン名の打ち間違いで頻度が多いものを提供してもよいでしょう。

別のドメインに移動するため

例えば、会社名が変わっても、既存のリンクやブックマークからも新しい会社名を見つけられるようにしたいでしょう。

HTTPS を強制するため

`http://` 版のサイトへのリクエストを `https://` 版のサイトにリダイレクトします。

### リンクの存続

ウェブサイトを再構築すると URL が変わります。サイトのリンクを新しい URL に合うよう更新しても、外部リソースからのリンクで使用されている URL を制御することはできません。

外部のリンクは貴重なユーザーを連れてきてくれるし、 SEO にも役立つため、リンクを壊したくはありません。よって、古い URL から新しい URL へのリダイレクトを設定します。

**メモ:** この手法は内部のリンクにも有効ですが、内部のリダイレクトは避けるようにしてください。リダイレクトは（追加の HTTP リクエストを行うため）性能の負担がかなりあります。内部のリンクを修正することでこれを避けられるのであれば、リンクを修正してください。

### 安全でないリクエストへの一時的なレスポンス

安全でないリクエストはサーバーの状態を変更するものであり、ユーザーがうっかり再実行するべきではありません。

一般的に、ユーザーは `PUT`、`POST`、`DELETE` のリクエストを再送信することは望みません。リクエストの結果としてレスポンスを返すだけである場合は、単に再読み込みボタンを押すことで (おそらく確認メッセージの後に)、リクエストを再送信します。

この場合、サーバーは正しい情報を持つ `303` (See Other) レスポンスを返すことができます。一方、再読み込みボタンが押された場合はページを再表示するだけであり、安全でないリクエストを再実行しません。

### 長いリクエストに対する一時的なレスポンス

`DELETE` リクエストを後で処理するように予定するなど、リクエストによってはサーバー側で長い時間が必要になる場合があります。この場合、レスポンスを `303` (See Other) として操作が実行予定に追加されたことを示すページにリンクし、最終的に進捗を確認したり、キャンセルできるようにしたりするようにします。

一般的なサーバーにおけるリダイレクトの設定
---------------------

### Apache

リダイレクトはサーバーの設定ファイルか、各ディレクトリの `.htaccess` で設定できます。

`mod_alias` モジュールには `Redirect` および `RedirectMatch` ディレクティブがあり、これらは既定で `302` レスポンスを設定します。

```xml
<VirtualHost \*:443>
  ServerName example.com
  Redirect / https://www.example.com
</VirtualHost>
```

URL `https://example.com/` は `https://www.example.com/` にリダイレクトされ、その下のファイルやディレクトリも同様です (`https://example.com/some-page` は `https://www.example.com/some-page` にリダイレクトされます)。

`RedirectMatch` も同じですが、対象の URL の集合を定義するために正規表現を使用します。
```

RedirectMatch ^/images/(.*)$ https://images.example.com/$1
```

`images/` フォルダー内のすべての文書が、別のドメインにリダイレクトされます。

一時的なリダイレクトを設定したくない場合は、別の種類のリダイレクトを設定するために追加引数 (使用する HTTP ステータスコードまたは `permanent` キーワード) を使用できます。
```

Redirect permanent / https://www.example.com
# …acts the same as:
Redirect 301 / https://www.example.com
```

`mod_rewrite` モジュールでリダイレクトを作成することもできます。こちらはさらに柔軟性がありますが、若干複雑です。

### Nginx

Nginx では、リダイレクトしたいコンテンツ用の server ブロックを作成します。
```

server {
  listen 80;
  server_name example.com;
  return 301 $scheme://www.example.com$request_uri;
}
```

ディレクトリまたは特定のページにのみリダイレクトを適用するには、`rewrite` ディレクティブを使用します。
```

rewrite ^/images/(.*)$ https://images.example.com/$1 redirect;
rewrite ^/images/(.*)$ https://images.example.com/$1 permanent;
```

### IIS

IIS では、`<httpRedirect>` 要素を使用してリダイレクトを設定します。

リダイレクトループ
---------

追加のリダイレクトが、すでに通っている経路をたどるとリダイレクトループが発生します。言い換えると終わらないループが存在しており、最終的に見つかるページはありません。

ほとんどの場合はサーバーの問題であり、サーバーで検出できる場合は `500` `Internal Server Error` を返すでしょう。サーバーの設定を変更した直後にこのようなエラーが発生した場合は、リダイレクトループが発生しているかもしれません。

時々、サーバーがリダイレクトループを検出しないことがあります。それぞれのサーバーでは全貌を把握できない、複数のサーバーにわたるリダイレクトループがあり得ます。この場合はブラウザーがループを検出して、エラーメッセージを表示するでしょう。Firefox では以下のメッセージを表示します。

>
> Firefox は、サーバーがこのアドレスへのリクエストを決して終了しない方法でリダイレクトしていることを検出しました。
>
>
>

Chrome では以下のように表示されます。

>
> このウェブページにはリダイレクト ループが含まれています
>
>
>

どちらの場合も、ユーザーができることはほとんどありません (キャッシュや Cookie の不一致など、ユーザー側で問題が発生している場合を除きます)。

リダイレクトループは使い勝手をを完全に損ないますので、避けることが重要です。


HTTP の基本 - HTTP

HTTP の基本
========

HTTP はとても拡張性のあるプロトコルです。リソースの記述や URI などわずかな基本概念に基づいており、メッセージ構造が単純で、コミュニケーションの流れはクライアント・サーバー構造です。これらの基本概念の上に、いくつもの拡張が何年にもわたって行われ、新しい機能や新しい意味が新しい HTTP メソッドやヘッダーによって追加されています。

記事
--

HTTP の概要

HTTP とは何であるか、そしてウェブアーキテクチャにおけるこのプロトコルの役割について説明します。

HTTP の進化

HTTP は 1990 年代初めに作成され、何度も拡張されました。この記事では、 HTTP/0.9、 HTTP/1.0、 HTTP/1.1、現代の HTTP/2、および長年にわたり導入されている小さなノベルティについての歴史を説明します。

HTTP バージョンのネゴシエーション

クライアントとサーバーが特定の HTTP バージョンをネゴシエートし、最終的に使用されたプロトコルバージョンをアップグレードする方法を説明します。

リソースと URI

ウェブ上のリソース、識別子、および場所の概念を簡単に紹介します。

ウェブ上のリソースの識別

ウェブリソースの参照方法とどのように配置されるのかについて説明します。

データ URI

それが表すリソースを直接埋め込む特定の種類の URI。データ URI はとても便利ですが、いくつかの注意点があります。

リソース URL
Non-standard

`resource:` というスキームの接頭辞が付いた URL は、 Firefox と Firefox のブラウザー拡張機能によってリソースを内部的に読み込むために使用されますが、情報の一部はブラウザーが接続するサイトでも利用できます。

リソースの識別と場所の分離: Alt-Svc HTTP ヘッダー

ほとんどの場合、ウェブリソースの識別子と場所は共有されますが、これは `Alt-Svc` ヘッダーで変更できます。

MIME タイプ

HTTP/1.0 以降では、様々なタイプのコンテンツを送信することができます。 この記事では `Content-Type` ヘッダーと MIME 標準を使用してこれがどのように行われるかについて説明します。

www URL とそうでない URL の選択

www という接頭辞のドメインを使うかどうかに関するアドバイスで、この記事では選択の結果とその作成方法について説明します。

HTTP セッションの流れ

この基本的な記事では典型的な HTTP セッションについて説明します。ブラウザーのリンクをクリックすると、何が起こるのでしょうか

HTTP メッセージ

HTTP リクエストまたはレスポンス中に送信されるメッセージは、非常に明確な構造を持っています。この入門記事ではその構造、目的、可能性について説明します。

HTTP/2 でのフレームとメッセージ構造

HTTP/2 は HTTP/1.x メッセージをカプセル化し、バイナリフレームで表現します。この記事ではフレームの構造、目的、エンコード方法について説明します。

HTTP/1.x でのコネクション管理

HTTP/1.1 は持続的な接続とパイプライン処理をサポートする HTTP の最初のバージョンでした。この記事ではこれらの 2 つの概念について説明します。

HTTP/2 でのコネクション管理

HTTP/2 では接続の作成方法とメンテナンス方法が完全に再考されました。この記事では HTTP フレームが多重化を許可し、以前の HTTP バージョンの 'head-of-line' ブロック問題を解決する方法について説明します。

コンテンツネゴシエーション

HTTP はブラウザーが好みの形式、言語、またはエンコーディングをアナウンスするための方法として `Accept-` から始まる一連のヘッダを導入しています。この記事ではこの宣言がどのように起こるか、サーバがどのように反応すると予想され、どのように最も適切な応答を選択するかについて説明します。


Network Error Logging - HTTP

Network Error Logging
=====================

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

ネットワークエラーロギングは、HTTP の `NEL` \*レスポンスヘッダー\*を使って設定できるメカニズムです。この実験的なヘッダーにより、ウェブサイトやアプリケーションは、対応しているブラウザーから、失敗した (必要であれば成功した) ネットワーク読み取りに関するレポートを受け取ることを選択することができます。

レポートは、 `Report-To` ヘッダーで定義された報告グループに送信されます。

使用方法
----

ウェブアプリケーションは、 \*JSON エンコード\*されたオブジェクトである NEL ヘッダーを使って、この動作を選択します。
```

NEL: { "report_to": "nel",
       "max_age": 31556952 }
```

ブラウザーから安全と認識されたオリジンが必要です。

以下のオブジェクトキーが NEL ヘッダーで指定されています。

report\_to

ネットワークエラーレポートの送信先となる Reporting API (en-US) グループです。

max\_age

ポリシーの有効期間を秒単位で指定します (HSTS ポリシーが時間制限されているのと同様の方法です)。参照される報告グループは、少なくとも NEL ポリシーと同程度の有効期間を持つ必要があります。

include\_subdomains

true の場合、ポリシーは、ポリシーヘッダーが設定されているオリジンの下のすべてのサブドメインに適用されます。このオプションを有効にする場合は、サブドメインを含めるように報告グループを設定する必要があります。

success\_fraction

0 と 1 の間の浮動小数点値で、報告するネットワーク要求が成功した割合を指定します。既定値は 0 で、JSON ペイロードにキーが存在しない場合、成功したネットワークリクエストは報告されません。

failure\_fraction

0 と 1 の間の浮動小数点値で、報告する**失敗した**ネットワークリクエストの割合を指定します。既定値は 1 で、JSON ペイロードにキーが存在しない場合、失敗したすべてのネットワークリクエストが報告されます。

上記のレポートグループは、 `Report-To` ヘッダー内で通常の方法で定義されます。例えば下記のようになります。
```

Report-To: { "group": "nel",
             "max_age": 31556952,
             "endpoints": [
               { "url": "https://example.com/csp-reports" }
             ] }
```

エラーレポート
-------

これらの例では、Reporting API のペイロード全体を示しています。最上位の **`"body"`** キーには、ネットワークエラーレポートが含まれています。

### HTTP 400 (Bad Request) response

```js
{
  "age": 20,
  "type": "network-error",
  "url": "https://example.com/previous-page",
  "body": {
    "elapsed\_time": 338,
    "method": "POST",
    "phase": "application",
    "protocol": "http/1.1",
    "referrer": "https://example.com/previous-page",
    "sampling\_fraction": 1,
    "server\_ip": "137.205.28.66",
    "status\_code": 400,
    "type": "http.error",
    "url": "https://example.com/bad-request"
  }
}
```

### DNS 名が未解決

なお、このレポートではフェーズが `dns` に設定されており、含めることのできる `server_ip` はありません。

```js
{
  "age": 20,
  "type": "network-error",
  "url": "https://example.com/previous-page",
  "body": {
    "elapsed\_time": 18,
    "method": "POST",
    "phase": "dns",
    "protocol": "http/1.1",
    "referrer": "https://example.com/previous-page",
    "sampling\_fraction": 1,
    "server\_ip": "",
    "status\_code": 0,
    "type": "dns.name\_not\_resolved",
    "url": "https://example-host.com/"
  }
}
```

ネットワークエラーの種類は、仕様で定義された以下の値のいずれかですが、ブラウザーは独自のエラー種別を追加して送信することができます。

`dns.unreachable`

ユーザーの DNS サーバーに到達できない

`dns.name_not_resolved`

ユーザーの DNS サーバーは応答したが、リクエストされた URI の IP アドレスに解決できなかった。

`dns.failed`

DNS サーバーへのリクエストが、以前のエラー (SERVFAIL など) でカバーされない理由で失敗した

`dns.address_changed`

セキュリティ上の理由から、オリジナルのレポートを配信したサーバーの IP アドレスが、エラー発生時の現在のサーバーの IP アドレスと異なる場合、レポートデータはこの問題に関する情報のみを含むようにダウングレードされ、タイプは `dns.address_changed` に設定されます。

`tcp.timed_out`

サーバーへの TCP コネクションがタイムアウトした

`tcp.closed`

TCP コネクションがサーバーから閉じられた

`tcp.reset`

TCP コネクションがリセットされた

`tcp.refused`

TCP コネクションがサーバーから拒否された

`tcp.aborted`

TCP コネクションが中止された

`tcp.address_invalid`

IP アドレスが無効である

`tcp.address_unreachable`

IP アドレスに到達できない

`tcp.failed`

TCP コネクションが直前のエラーによってカバーできない原因で失敗した

`http.error`

ユーザーエージェントがレスポンスの受信に成功したが、 4xx または 5xx のステータスコードであった

`http.protocol.error`

コネクションが HTTP プロトコルエラーのために中止された

`http.response.invalid`

レスポンスが空であるか、 content-length が合っていないか、エンコーディングが正しくないか、その他の状況でユーザーエージェントがレスポンスを処理できなかった

`http.response.redirect_loop`

リクエストはリダイレクトループが検出されたため中止された

`http.failed`

コネクションは直前のエラーでカバーされなかった HTTP プロトコルのエラーで失敗した

仕様書
---

| 仕様書 |
| --- |
| Network Error Logging |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Permissions Policy - HTTP

Permissions Policy
==================

機能ポリシーで、ウェブ開発者はブラウザーの特定の機能や API を有効化、無効化したり、動作を変更したりすることができます。これはコンテンツセキュリティポリシーに似ていますが、セキュリティの動作ではなく機能の制御を行うものです。

概要
--

機能ポリシーは、ウェブサイト全体でどの機能が使用されるか (または使用されないか) を明示的に宣言する仕組みを提供します。これにより、使用可能な機能を制限することによって、コードベースが時とともに進化し — サードパーティーのコンテンツをより安全に構成する場合と同様に — ベストプラクティスを維持することができます。

機能ポリシーでは、ブラウザーがウェブサイト全体で使用されている特定の機能を実施するための一連の「ポリシー」を選択します。これらのポリシーは、サイトがアクセスできる API を制限したり、特定の機能についてブラウザーの既定の動作を変更したりすることができます。

機能ポリシーで行うことができるものの例です。

* モバイル環境でサードパーティの動画の自動再生の既定の動作を変更する。
* カメラやマイクなどの注意が必要な API をサイトが使用することを制限する。
* iframe から全画面 API が利用できるようにする。
* 同期 XHR や `document.write()` のような古い API の使用をブロックする。
* 画像が正しい大きさであり、ビューポートに対して大きすぎないことを確認する。
概念と使い方
------

機能ポリシーを使用すると、最上位ページと埋め込みフレームの両方で、どのオリジンがどの機能を使用できるかを制御できます。基本的には、各機能が許可されたオリジンの一覧であるポリシーを記述します。機能ポリシーによって制御されるそれぞれの機能は、その機能がオリジンが許可されたオリジンのリスト内で一致した場合のみ現在の文書やフレームで有効になります。

ポリシーによって制御される各機能について、ブラウザーは機能が有効になっているオリジンの一覧、すなわち許可リストを管理します。ある機能のポリシーを設定していない場合は、既定の許可リストが使用されます。既定の許可リストは機能別に定められています。

### ポリシーを書く

ポリシーは、個々のポリシーディレクティブのセットを使用して記述します。ポリシーディレクティブは定義済みの機能名と、その機能を使用することができるオリジンの許可リストの組み合わせです。

### ポリシーの指定

機能ポリシーでは、機能を制御するポリシーを指定する方法を 2 つ提供しています。

* `Permissions-Policy` HTTP ヘッダー
* iframe の `allow` 属性

HTTP ヘッダーと allow 属性の主な違いは、 allow 属性が iframe 内の機能のみを制御することです。ヘッダーは、レスポンス内とそのページ内の埋め込みコンテンツの機能を制御します。

詳細は機能ポリシーの使用を参照してください。

### ポリシーの推定

スクリプトは、 `Document.featurePolicy` または `HTMLIFrameElement.featurePolicy` にある `FeaturePolicy` (en-US) オブジェクトを通して機能ポリシーに関する情報をプログラム的に取得することができます。

ポリシーで制御する機能の種類
--------------

機能ポリシーは一貫した構文を使用して複数の機能の制御を提供しますが、ポリシー制御機能の動作はさまざまで、いくつかの要因によって異なります。

一般的な原則では、機能が無効になっているときにウェブ開発者がそれを判断し、対策するための直感的または妨害しない方法があるべきであるということです。新しく導入された機能には、状態を通知するための明示的な API がある場合があります。後で機能ポリシーと統合される既存の機能は、通常、既存のメカニズムを使用します。アプローチには次のようなものがあります。

* Return "permission denied" for JavaScript APIs that require user permission grants.
* Return `false` or error from an existing JavaScript API that provides access to feature.
* Change the default values or options that control the feature behavior.

現在のポリシー制御機能のセットは、大きく 2 つのカテゴリに分類されます。

* Enforcing best practices for good user experiences.
* Providing granular control over sensitive or powerful features.
### 使い勝手を高めるためのベストプラクティス

優れたパフォーマンスとユーザーエクスペリエンスを提供するためのベストプラクティスを実施するのに役立つポリシー制御の機能がいくつかあります。

ほとんどの場合、ポリシーによって制御される機能は、使用時にユーザーエクスペリエンスに悪影響を与える機能を表します。既存のウェブコンテンツが壊れるのを防ぐため、このようなポリシー制御機能のデフォルトは、すべての起点で機能を使用できるようにすることです。ベストプラクティスは、ポリシー制御機能を無効にするポリシーを使用することによって実施されます。詳細は「優れたユーザーエクスペリエンスのためのベストプラクティスの実施」を参照してください。

The features include:

* Layout-inducing animations
* Legacy image formats
* Oversized images
* Synchronous scripts
* Synchronous XMLHTTPRequest
* Unoptimized images
* Unsized media
### 特定の機能に対する細かい制御

ウェブは、悪用された場合にプライバシーやセキュリティ上のリスクを伴う可能性のある機能や API を提供します。場合によっては、そのような機能がウェブサイト上でどのように使用されるかを厳密に制限することもできます。ウェブサイト内の特定の原点やフレームに対して機能を有効/無効にするポリシー制御の機能があります。利用可能な場合、機能は Permissions API、または機能が利用可能かどうかを確認する機能固有のメカニズムと統合されます。

機能には以下のものが含まれます (機能一覧を参照してください)。

* Accelerometer
* Ambient light sensor
* Autoplay
* Camera
* Encrypted media
* Fullscreen
* Geolocation
* Gyroscope
* Magnetometer
* Microphone
* Midi
* PaymentRequest
* Picture-in-picture
* USB
* VR / XR
例
-

* 機能ポリシーの使用
* 数多くのポリシーの使用例については Feature Policy Demos をご覧ください。
仕様書
---

| Specification |
| --- |
| Permissions Policy # permissions-policy-http-header-field |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* 機能ポリシーの使用
* HTTP の `Permissions-Policy` ヘッダー
* iframe の `allow` 属性
* Introduction to Feature Policy
* Feature policies on www.chromestatus.com
* Feature-Policy Tester (Chrome Developer Tools extension)
* プライバシー、アクセス許可、情報セキュリティ


HTTP リクエストメソッド - HTTP

HTTP リクエストメソッド
==============

HTTP では、リソースに対して実行したいアクションを示す一連の**リクエストメソッド**を定義しています。リクエストメソッドは *HTTP 述語*と呼ばれることがありますが、名詞も存在します。それぞれのメソッドがさまざまな意味を持っていますが、いくつかの共通的な機能が、メソッドのグループで共有されています。例えば、リクエストメソッドは安全、べき等、キャッシュ可能であることがあります。

`GET`

`GET` メソッドは、指定したリソースの表現をリクエストします。 `GET` を使用するリクエストは、データの取り込みに限ります。

`HEAD`

`HEAD` メソッドは `GET` リクエストと同じレスポンスを、レスポンス本文なしで求めます。

`POST`

`POST` は指定したリソースに実体を送信するために使用するメソッドであり、サーバー上の状態を変更したり、副作用が発生したりすることがよくあります。

`PUT`

`PUT` メソッドは対象リソースの現在の表現全体を、リクエストのペイロードで置き換えます。

`DELETE`

`DELETE` メソッドは、指定したリソースを削除します。

`CONNECT`

`CONNECT` メソッドは、対象リソースで識別されるサーバーとの間にトンネルを確立します。

`OPTIONS`

`OPTIONS` メソッドは、対象リソースの通信オプションを示すために使用します。

`TRACE`

`TRACE` メソッドは、対象リソースへのパスに沿ってメッセージのループバックテストを実行します。

`PATCH`

`PATCH` メソッドは、リソースを部分的に変更するために使用します。

仕様書
---

| 仕様書 | 表題 | 備考 |
| --- | --- | --- |
| RFC 7231, セクション 4: Request methods | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE を定義。 |
| RFC 5789, セクション 2: Patch method | PATCH Method for HTTP | PATCH を定義。 |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* HTTP ヘッダー


HTTP/1.x のコネクション管理 - HTTP

HTTP/1.x のコネクション管理
==================

コネクション管理は、 HTTP の重要なトピックです。コネクションを開いたり管理したりすることは、ウェブサイトやウェブアプリケーションのパフォーマンスに大きな影響を与えます。HTTP/1.x では*短命な (short-lived) コネクション*、*持続的な (persistent) コネクション*、*HTTP パイプライン*といったモデルがあります。

HTTP は、クライアントとサーバーの間のコネクションを提供するトランスポートプロトコルを、たいてい TCP に依存しています。初期のころ、 HTTP が使用するコネクションの制御モデルは 1 種類でした。それらのコネクションは短命です。リクエストの送信が必要になるたびに新たなコネクションを作成して、回答を受け取るとコネクションを閉じていました。

このシンプルなモデルは、先天的なパフォーマンスの制約を抱えていました。それぞれの TCP コネクションを開く処理は、リソースを消費します。いくつかのメッセージを、クライアントとサーバーの間で交換しなければなりません。リクエストの送信が必要になると、ネットワークの遅延や帯域がパフォーマンスに影響を与えます。現代のウェブページは、必要な情報を提供するために多くのリクエスト (1 ダース以上) を必要としており、初期のモデルが非効率であることを実証しています。

HTTP/1.1 で、新たなモデルを 2 種類導入しました。持続的なコネクションモデルは、連続したリクエストの間はコネクションを開き続けておくことで、新たなコネクションを開始するために必要な時間を削減します。 HTTP パイプラインモデルはさらに 1 歩進んで、回答を待っている間も複数の連続したリクエストを送信して、ネットワークの遅延の大部分を削減します。

![HTTP/1.x の3つのコネクションモデルにおけるパフォーマンスの比較: 短命なコネクション、持続的なコネクション、 HTTP パイプライン](/ja/docs/Web/HTTP/Connection_management_in_HTTP_1.x/http1_x_connections.png)

**メモ:** HTTP/2 では、コネクションの管理モデルをさらに追加しました。

特筆すべき重要なポイントとして、 HTTP のコネクション管理は隣接したノードの間のコネクション、すなわちエンドツーエンドではなくホップバイホップに適用されることがあります。クライアントと最初のプロキシの間で使用するモデルと、プロキシと宛先サーバー (または任意の中間プロキシ) の間で使用するモデルが異なることもあります。`Connection` や `Keep-Alive` といったコネクションモデルの定義にかかわる HTTP ヘッダーは、中間のノードが値を変更できる ホップバイホップ ヘッダーです。

関連するトピックとしては、 HTTP コネクションのアップグレードの概念、つまり HTTP/1.1 コネクションが TLS/1.0、 WebSocket、 又は平文の HTTP/2 のような異なるプロトコルにアップグレードされたことが挙げられます。このプロトコルのアップグレードメカニズム (en-US)は他の場所でもっと詳しく文書化されています。

短命なコネクション
---------

*短命なコネクション*は HTTP の初期のモデルであり、 HTTP/1.0 の既定のモデルです。それぞれの HTTP リクエストは、自身のコネクションで完結します。すなわち、各 HTTP リクエストの前に TCP のハンドシェイクが発生します。また、それらが連続します。

TCP のハンドシェイク自体は時間がかかる処理ですが、 TCP のコネクションはその負荷に適応しており、より持続するコネクションによって効率が向上します。短命なコネクションは TCP の効率化機能を使用しておらず、また新たなコールド状態のコネクションで送信することに固執するため最適な状態よりもパフォーマンスが低下します。

このモデルは HTTP/1.0 で使用する既定のモデルです (`Connection` ヘッダーが存在しない、あるいはヘッダーの値が `close` である場合)。 HTTP/1.1 では、 `Connection` ヘッダーで `close` の値が送信された場合に限り、このモデルを使用します。

**メモ:** とても古い (持続的なコネクションをサポートしていない) システムを扱う場合を除き、あえてこのモデルを使用する理由はありません。

持続的なコネクション
----------

短命なコネクションには、大きな問題点が 2 つあります。新しいコネクションを確立するためにかなり時間がかかること、および下層の TCP コネクションは何度も使用するとき (ウォーム状態のコネクション) しかパフォーマンスが向上しないことです。これらの問題を緩和するため、 HTTP/1.1 より前から*持続的なコネクション*の概念が考えられてきました。あるいは、*キープアライブ接続*と呼ばれることもあります。

持続的なコネクションはしばらくの間開かれたままであり、いくつかのリクエストで再使用できます。よって新たな TCP ハンドシェイクにかかる時間を節約して、 TCP のパフォーマンス向上機能を活用します。このコネクションはいつまでも開かれたままにはなりません。アイドル状態のコネクションはしばらく後に閉じられます (サーバーは、コネクションを開き続けておくべき最小時間を決めるために `Keep-Alive` ヘッダーを使用するでしょう)。

持続的な接続には欠点もあります。アイドル状態でもサーバーのリソースを消費しており、高負荷状態では DoS 攻撃 を招く可能性があります。この場合、持続的ではない接続はアイドル状態になるとすぐに閉じられますので、パフォーマンスが向上するでしょう。

HTTP/1.0 の既定のコネクションは、持続的ではありません。 `Connection` を `close` 以外の何か、通常は `retry-after` に設定すると、持続的になります。

HTTP/1.1 では既定で持続的であり、ヘッダーは不要になりました (ただし HTTP/1.0 へのフォールバックが必要な場合の防衛策として、通常はヘッダーを追加します。)。

HTTP パイプライン
-----------

**メモ:** HTTP パイプラインは、現代のブラウザーでは既定で有効化されていません。

* 不具合があるプロキシがまだ一般的であり、これらは開発者が容易には予見あるいは診断できない、奇妙かつ一定しない挙動の原因になります。
* パイプラインの正しい実装は複雑です。転送するリソースのサイズ、効果的な RTT および帯域が、パイプラインによる改善に対して直接的な影響力を持ちます。これらがわからなければ、重要なメッセージがそうでないメッセージより遅れる場合があります。重要さの概念は、ページのレイアウト中に高まります!よって、 HTTP パイプラインはほとんどの場合でわずかな改善にしかなりません。
* パイプラインは、 HOL の問題に左右されます。

これらの理由により、パイプラインはよりよいアルゴリズムである*多重化*に置き換えられました。こちらは HTTP/2 で使用されています。

既定で、HTTP リクエストは順次発行されます。次のリクエストは、現在のリクエストのレスポンスが到着してから発行されます。これはネットワークの遅延や帯域の制約を受けるため、次のリクエストがサーバーで*見える*ようになるまでにかなりの遅延が発生する可能性があります。

パイプラインは連続したリクエストを同一の持続的なコネクションで、回答を待たずに処理します。これは、コネクションの遅延を回避します。理論上は、2 つのリクエストを同じ TCP メッセージに収めた場合でもパフォーマンスが向上するでしょう。典型的な MSS (最大セグメントサイズ) は複数のシンプルをリクエストを収めるには十分な大きさですが、 HTTP リクエストのサイズの需要は増え続けています。

パイプライン化できない HTTP リクエストもあります。 べき等 なメソッドである `GET`, `HEAD`, `PUT`, `DELETE` だけが安全に再実行できます。これらは失敗しても、パイプラインの内容を再実行できます。

現在、すべての HTTP/1.1 に準拠するプロキシやサーバーはパイプラインをサポートしているはずですが、実際は多くの制限があります。さまざまな理由で、現行のブラウザーはパイプラインを既定で有効化していません。

ドメインシャーディング
-----------

**メモ:** 特別に必要である場合を除き、この非推奨の技術は使用しないでください。代わりに、 HTTP/2 に切り替えてください。 HTTP/2 では、ドメインシャーディングは有用ではありません。 HTTP/2 のコネクションは、並行した優先度がないリクエストをより上手に扱うことができます。また、ドメインシャーディングはパフォーマンスに悪影響を与えます。ほとんどの HTTP/2 実装では、最終的にドメインシャーディングに戻る connection coalescing と呼ばれる技術を使用しています。

HTTP/1.x のコネクションはリクエストが整理されることもなく連続するため、十分な帯域を使用できない状況では最適化できません。その解決策として、ブラウザーはそれぞれのドメインに対して複数のコネクションを開いて、リクエストを並行して送信します。既定では一度に 2 から 3 つのコネクションですが、現在は主に 6 つの並列したコネクションへ増えています。この数をさらに増やそうとすると、サーバー側で DoS 防御が発動する危険性があります。

サーバーがウェブサイトやウェブアプリケーションのレスポンスを早くしたい場合、より多くのコネクションを開かせることが考えられます。例えば、すべてのリソースを同じドメイン `www.example.com` で持つのではなく、`www1.example.com`、`www2.example.com`、`www3.example.com` といった複数のドメインに分散させることができます。それぞれのドメインは*同じ*サーバーに名前解決されて、ウェブブラウザーはドメインごとに 6 つのコネクションを開きます (この例では、コネクション数が 18 に増加します)。この技術は*ドメインシャーディング*と呼ばれます。

![](/ja/docs/Web/HTTP/Connection_management_in_HTTP_1.x/httpsharding.png)

まとめ
---

改良されたコネクション管理により、 HTTP のパフォーマンスを大きく向上できます。 HTTP/1.1 や HTTP/1.0 では、持続的なコネクションを使用します。少なくともコネクションがアイドル状態になるまで、最良のパフォーマンスになります。一方、パイプラインの失敗は優れたコネクション管理モデルの設計を促し、それは HTTP/2 に導入されました。


コンテンツネゴシエーション - HTTP

コンテンツネゴシエーション
=============

HTTP において**コンテンツネゴシエーション** (content negotiation) は、同じ URI におけるさまざまな表現のリソースを提供するために使用する仕組みであり、ユーザーエージェントはどのリソースがユーザーにもっとも適しているか（例えば文書の言語はどれか、画像形式はどれか、コンテンツエンコーディングはどれか）を指定することができます。

**メモ:** WHATWG のウィキページには、 HTTP コンテンツネゴシエーションの短所がいくつか書かれています。 HTML では、コンテンツネゴシエーションの代替として、例えば `<source>` 要素を提供しています。

### コンテンツネゴシエーションの原理

特定の文書はリソース (*resource*) と呼ばれます。クライアントがリソースを取得したいときは、 URL でリクエストします。サーバーはこの URL を使用して、表現 (*representation*) と呼ばれる利用可能な変化形–特定の表現をクライアントに返します。それぞれの表現を含むリソース全体が一つの特定の URL を持ちます。**コンテンツネゴシエーション**は、リソースが呼び出されたときに特定の表現を選択する方法を定めます。クライアントサーバーの間でネゴシエーションする方法がいくつかあります。

![URL をリクエストしているクライアント。サーバーには URL で表される複数のリソースがあり、リクエストに基づいて適切なコンテンツを返送します。](/ja/docs/Web/HTTP/Content_negotiation/httpnego.png)

最適な表現は、以下の 2 つの仕組みのいずれかによって識別されます。

* クライアントによる特定の HTTP ヘッダー (*サーバー駆動型ネゴシエーション*または*プロアクティブネゴシエーション*)。これは、特定の種類のリソースでネゴシエーションを行う標準的な方法です。
* サーバーによる `300` (Multiple Choices)、`406` (Not Acceptable)、`415` (Unsupported Media Type) のいずれかの HTTP レスポンスコード（*エージェント駆動型ネゴシエーション*または*リアクティブネゴシエーション*）。これはフォールバック機構として使用します。

数年来、透過的コンテンツネゴシエーション (transparent content negotiation) や `Alternates` ヘッダーといった他のコンテンツネゴシエーションが提案されてきました。これらは支持を得られず、破棄されました。

サーバー駆動型コンテンツネゴシエーション
--------------------

**サーバー駆動型コンテンツネゴシエーション**またはプロアクティブコンテンツネゴシエーションでは、ブラウザー（または他の種類のユーザー エージェント）はいくつかの HTTP ヘッダーを URL と一緒に送信します。これらのヘッダーには、ユーザーが希望する選択肢を記述します。サーバーはこれらをヒントとして使い、内部アルゴリズムがクライアントに提供する最適なコンテンツを選択します。適切なリソースを提供できない場合、 `406` (Not Acceptable) または `415` (Unsupported Media Type) で応答し、対応しているメディアタイプのヘッダーを設定します（たとえば、POST と PATCH リクエストに対しては、それぞれ `Accept-Post` (en-US) または `Accept-Patch` を使用します）。このアルゴリズムはサーバーに依存し、標準では定義されていません。 Apache ネゴシエーションアルゴリズム をご覧ください。

![コンテンツタイプを推奨するヘッダーを持つ URL をリクエストされたクライアント。サーバーは URL で表される複数のリソースを持っており、クライアントのリクエストヘッダーを尊重しながら、推奨する言語のコンテンツを返送し、リクエスト本体を圧縮します。](/ja/docs/Web/HTTP/Content_negotiation/httpnegoserver.png)

HTTP/1.1 標準では、サーバー駆動型ネゴシエーションを開始する標準ヘッダーの一覧（例えば `Accept`, `Accept-Encoding`, `Accept-Language`）を定義しています。厳密に言えば `User-Agent` はこの一覧に含まれていませんが、リクエストしたリソースの特定の表現を送信するために使用されることがあります。ただし、これはよい習慣ではないと考えられています。サーバーはどのヘッダーを実際にコンテンツネゴシエーションで使用したかを示すために `Vary` ヘッダー（あるいは、より的確な関係があるレスポンスヘッダー）を使用します。これにより、キャッシュが適切に機能します。

さらに、ネゴシエーションに使用できるヘッダーを追加する実験的な提案があり、*クライアントヒント*と呼ばれています。クライアントヒントは、ユーザーエージェントを実行している端末がどのようなものか（例えば、デスクトップコンピューターかモバイル端末か）を伝えます。

サーバー駆動型コンテンツネゴシエーションは、リソースの特定の表現を決定するためのもっとも一般的な方法ですが、いくつか欠点があります。

* サーバーは、ブラウザーのことをすべて知っているわけではありません。クライアント拡張を加えても、ブラウザーの機能を完全には把握できません。クライアントが選択するリアクティブコンテンツネゴシエーションとは異なり、サーバーの選択は常に少し独断的です。
* クライアントが提供する情報はかなり冗長であり（HTTP/2 のヘッダー圧縮は、この問題を緩和します）、またプライバシーのリスク（HTTP フィンガープリンティング）もあります。
* 指定されたリソースの複数の表現を送信すると、共有キャッシュの効率が下がります。また、サーバーの実装がより複雑になります。
### `Accept` ヘッダー

`Accept` ヘッダーは、エージェントが処理することを望むメディアリソースの MIME タイプを羅列します。これはカンマ区切りの MIME タイプのリストで、それぞれの MIME タイプは、別の MIME タイプとの相対的な優先度を示す引数である品質係数と結びつけられています。

`Accept` ヘッダーは、ブラウザーまたは他のユーザーエージェントによって定義され、そのコンテキストによって変わることがあります。例えば、取得するものが HTML ページ、画像、動画、スクリプトなどに変わります。アドレスバーで指定した文書を取得するときと `<img>`, `<video>`, `<audio>` 要素でリンクしたものを取得するときで異なります。ブラウザーはこのヘッダーで、最適と思われる値を自由に使用できます。一般的なブラウザーの既定値の包括的な一覧があります。

### `Accept-CH` ヘッダー
Experimental

**メモ:** これは*クライアントヒント (Client Hints)* と呼ばれる**実験的**な技術の一部であり、現在は Chrome 46 以降が実装しています。 Device-Memory の値は Chrome 61 以降が実装しています。

`Accept-CH` は実験的なもので、サーバーが適切なリソースを選択するために使用できる設定データを羅列します。有効な値は以下のとおりです。

| 値 | 意味 |
| --- | --- |
| `Device-Memory` | 端末に搭載されている RAM のおおよその量を示します。この値は、 2 の整数乗を 1024 で割った近似値です。たとえば、 512 メガバイトは `0.5` として報告されます。 |
| `Viewport-Width` | レイアウトビューポートの幅を CSS ピクセルで示します。 |
| `Width` | リソースの幅を物理ピクセルで示します（言い換えると、画像の本来の幅です）。 |

### `Accept-CH-Lifetime` ヘッダー

**メモ:** これは*クライアントヒント (Client Hints)* と呼ばれる**実験的**な技術の一部であり、 Chrome 61 以降でのみ利用できます。

`Accept-CH-Lifetime` ヘッダーは、 `Accept-CH` ヘッダーの `Device-Memory` 値と共に使用され、端末がメモリーの量をサーバーと共有することを許可すべき時間を示します。値はミリ秒単位で与えられ、使用は任意です。

### `Accept-Encoding` ヘッダー

`Accept-Encoding` ヘッダーは、コンテンツの受け入れ可能なエンコーディング（対応する圧縮方式）を定義します。この値は、エンコーディングの優先度を示す Q 値のリスト (例: `br, gzip;q=0.8`) です。既定値 `identity` は（ほかに指定されていなければ）優先度が最低です。

HTTP メッセージの圧縮はウェブサイトのパフォーマンスを向上させるためにもっとも有力な手段のひとつであり、転送するデータのサイズを削減して利用可能な帯域を有効活用します。ブラウザーは常にこのヘッダーを送信し、またサーバーはこのヘッダーを受け入れるように設定して、圧縮を行うべきです。

### `Accept-Language` ヘッダー

`Accept-Language` ヘッダーは、ユーザーの言語設定を示すために使用します。これは、品質係数を伴う値のリストです（例: `"de, en;q=0.7`"）。既定値はたいてい、ユーザーエージェントのグラフィカルインターフェイスの言語に従いますが、ほとんどのブラウザーでは異なる言語を設定できます。

設定に基づくエントロピーが高まるため、変更された値はユーザーのフィンガープリントとして使用される可能性があります。値を変更することは推奨されておらず、ウェブサイトは、この値がユーザーの本当の希望を反映していると信じてはいけません。このヘッダーで言語検出を行うと、使い勝手を損なう可能性があるため、サイトのデザイナーは使用することを避けてください。

* サイトデザイナーは常に、サーバーが選択した言語を変える手段を、例えばサイト上に言語切り替えメニューを提供するなりして提供するべきです。多くのユーザーエージェントは `Accept-Language` ヘッダーに、ユーザーインターフェイス言語に合わせた既定値を提供します。エンドユーザーは大抵、この設定を変更しません。変更する方法を知らなかったり、コンピューティング環境の都合で変更できなかったりするからです。
* サーバーが選択した言語をユーザーが変更したら、サイトは言語検出を使用せず、明示的に指定された言語に従うべきです。言い換えると、このヘッダーを使用して適切な言語を選択するのは、サイトの入口のページだけとするべきです。
### `User-Agent` ヘッダー

**メモ:** コンテンツの選択にこのヘッダーを使用することは、正当な使用方法ですが、ユーザーエージェントがどの機能に対応しているかを判断するためにこのヘッダーを頼ることは悪い習慣であると考えられています。

`User-Agent` ヘッダーは、リクエストを送信するブラウザーを識別します。この文字列には、空白区切りで*製品トークン*や*コメント*のリストが含まれることがあります。

*製品トークン*は `Firefox/4.0.1` のように、名称、スラッシュ '`/`'、バージョン番号で構成されます。ユーザーエージェントは好きなだけこれを入れることができます。*コメント*は、括弧で囲まれた任意の文字列です。当然ながら、その文字列内で括弧を使用することはできません。コメントの内部形式は標準化されておらず、従って各ブラウザーがさまざまなトークンをセミコロン '`;`' 区切りで入れています。

### `Vary` レスポンスヘッダー

クライアントが送信する前出の `Accept-*` ヘッダーとは対照的に、 `Vary` HTTP ヘッダーはウェブサーバーがレスポンスで送信します。これは、サーバーがサーバー駆動型コンテンツネゴシエーションで使用したヘッダーのリストを示します。このヘッダーはネゴシエーションを再現できるように、判断基準のキャッシュを知らせるために必要であり、キャッシュが機能を果たすようにするとともに、ユーザーに誤ったコンテンツを提供することを防ぎます。

特別な値 '`*`' は、サーバー駆動型コンテンツネゴシエーションで適切なコンテンツを選ぶために、ヘッダーで与えられていない情報も使用することを表します。

`Vary` ヘッダーは HTTP バージョン 1.1 で追加され、キャッシュが適切に働くようにするためのものです。サーバー駆動型コンテンツネゴシエーションで動作させるためには、転送されたコンテンツを選択するためにサーバーが使用した基準をキャッシュが知らなければなりません。この方法で、キャッシュはコンテンツ選択のアルゴリズムを再生することを可能にして、サーバーへさらにリクエストを行うことなく適切なコンテンツを直接提供できるでしょう。当然ながらワイルドカード '`*`' は、背後にある要素をキャッシュで知ることができないため、キャッシュの生成を妨げます。詳しくは、 HTTP キャッシュ > 変化するレスポンスを参照してください。

エージェント駆動型ネゴシエーション
-----------------

サーバー駆動型ネゴシエーションには、うまくスケーリングできないという欠点があります。ネゴシエーションでは、ひとつの機能に対してひとつのヘッダーを使用します。画面サイズ、解像度、または他の軸を使用したい場合は、新たな HTTP ヘッダーを作成する必要があります。このヘッダーを、すべてのリクエストで送信しなければなりません。ヘッダーが少ない場合は問題にはなりませんが、ヘッダーの数が増えると、最終的にはメッセージの大きさがパフォーマンスに影響を与える可能性があります。多くの詳細なヘッダーを送信するとエントロピーも多く送信されますので、 HTTP フィンガープリンティングの可能性やそれに伴うプライバシーの懸念が増大します。

HTTP では、もうひとつのネゴシエーション方法である*エージェント駆動型ネゴシエーション*または*リアクティブネゴシエーション*が利用できます。この場合、サーバーはあいまいなリクエストに直面したときに、利用可能な代替リソースへのリンクを含むページを送り返します。ユーザーはそのリソースを提示され、使用するリソースを選択します。

![クライアントが、コンテンツタイプを推奨するヘッダーを持つ URL をリクエストされた場合。サーバーは URL で表される複数のリソースを持ち、複数のレスポンスを返します。そのため、クライアントは好みの圧縮アルゴリズムが適用された本体を選ぶことができます。](/ja/docs/Web/HTTP/Content_negotiation/httpnego3.png)

残念ながら HTTP 標準では、使用可能なリソースを選択するためのページの様式を定めていないため、このプロセスを自動化することができません。この方法は、**サーバー駆動型ネゴシエーション**のフォールバックのほかにも、スクリプト、特に JavaScript のリダイレクトで常に使われています。ネゴシエーション基準を確認した後、スクリプトがリダイレクトを実行します。第二の問題点は、実際のリソースを取り出すために複数のリクエストが必要であるため、ユーザーがリソースを利用可能になるのが遅くなることです。


Cross-Origin Resource Policy (CORP) - HTTP

Cross-Origin Resource Policy (CORP)
===================================

**クロスオリジンリソースポリシー**は `Cross-Origin-Resource-Policy` ヘッダーによって設定されるポリシーで、ウェブサイトやアプリケーションが他のオリジンから (`<script>` や `<img>` などの要素を使用して発行された) 特定のリクエストに対する保護をオプトインすることで、 Spectre のような投機的なサイドチャネル攻撃や、クロスサイトスクリプトインクルージョン攻撃を緩和することができます。

CORP は既定で same-origin policy を超えた保護の追加レイヤーです。クロスオリジンリソースポリシーは、既定でクロスオリジンの読み込みを保護するメカニズムである、 クロスオリジンリードブロッキング (CORB)を補完します。

**メモ:** このポリシーは、既定で CORS セーフリストメソッド／ヘッダーに対して発行される、`no-cors` リクエストに対してのみ有効です。

このポリシーは\*レスポンスヘッダー*を介して表現されるため、実際のリクエストは防止されません。むしろ、ブラウザーは応答本文を削除することで*結果\*が漏洩するのを防ぎます。

歴史
--

コンセプトは 2012 年に（`From-Origin`として）元々提案されましたが、2018 年の Q2 に再提案されて Safari と Chromium に実装されました。

2018 年の前半に、*Meltdown* と *Spectre* として知られる 2 つのサイドチャネルハードウェア脆弱性が公表されました。パフォーマンスを改善するために設計された投機的実行機能の一部として生じた競合状態により、これらの脆弱性は機密性の高いデータを漏洩することができます。

これを受けて Chromium は Cross-Origin Read Blocking を実装しました。これにより、クロスオリジンの読み込みに対してリソース（`Content-Type` が HTML、JSON、XML）を自動的に保護します。アプリケーションが `no-sniff` ディレクティブを渡していない場合、Chromium は `Content-Type` を推測しようと試みて、とにかく保護を適用します。

クロスオリジンリソースポリシーは*どのような*リソースでも保護することができるオプトインのレスポンスヘッダーです。ブラウザーが MIME タイプを嗅ぎ分ける必要はありません。

使用方法
----

**メモ:** Chrome のバグが原因で、クロスオリジンリソースポリシーが PDF の描画を破壊し、訪問者が PDF の 1 ページ目以降を読めない可能性があります。本番環境ではこのヘッダーの仕様には注意してください。

ウェブアプリケーションは、次の 3 つの値の中から 1 つ受け取ることができる `Cross-Origin-Resource-Policy` の HTTP レスポンスヘッダーを介してクロスオリジンリソースポリシーを設定します。

same-site

同じ *Site* からのリクエストのみリソースを読み込めます。

**警告:** これはオリジンよりも安全性が低いものです。2 つのオリジンが同じサイトであるかどうかをチェックするアルゴリズムは HTML 標準で定義されており、*登録可能なドメイン*をチェックします。

same-origin

同じ *origin* (すなわち、スキーマ + ホスト + ポート) からのリクエストのみリソースを読み込めます。

cross-origin

いかなる *origin* (same-site と cross-site 両方) からのリクエストでもリソースを読み込めます。

```

Cross-Origin-Resource-Policy: same-site | same-origin | cross-origin
```

クロスオリジンリソースポリシーチェックの際に、ヘッダーが設定されている場合、ブラウザーは異なるオリジンやサイトから発行された `no-cors` リクエストを拒否します。

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

仕様書
---

| Specification |
| --- |
| Fetch Standard # cross-origin-resource-policy-header |

関連情報
----

* `Cross-Origin-Resource-Policy` HTTP Header
* Bugzilla bug 1459573


HTTP 範囲リクエスト - HTTP

HTTP 範囲リクエスト
============

HTTP 範囲リクエストでは、サーバーからクライアントに HTTP メッセージの一部のみを送信できます。部分リクエストは、たとえば、大きなメディアや、一時停止や再開機能を持つファイルのダウンロードに役立ちます。

サーバーが部分リクエストに対応しているかどうかの確認
--------------------------

`Accept-Ranges` が HTTP レスポンスに存在した場合 (そして値が "`none`" ではない場合)、サーバーは範囲リクエストに対応しています。これは例えば、 `HEAD` リクエストを cURL で発行することで確認することができます。
```

curl -I http://i.imgur.com/z4d4kWk.jpg

HTTP/1.1 200 OK
...
Accept-Ranges: bytes
Content-Length: 146515
```

このレスポンスの中で、 `Accept-Ranges: bytes` は範囲を定義する単位としてバイト数が使えることを示しています。ここで `Content-Length` ヘッダーも受け取る画像の全体の長さを示すので有用です。

サイトが `Accept-Ranges` ヘッダーを省略した場合は、おそらく部分リクエストに対応していません。サイトによっては値として明示的に "`none`" を送信して、対応がないことを示すこともあります。アプリによっては、このような場合にダウンロードマネージャーが一時停止ボタンを無効化します。
```

curl -I https://www.youtube.com/watch?v=EwTZ2xpQwpA

HTTP/1.1 200 OK
...
Accept-Ranges: none
```

サーバーからの特定の範囲のリクエスト
------------------

サーバーが範囲リクエストをサポートしている場合、そのリクエストを`Range`で発行することができ、それはサーバーが返すべきドキュメントの一部分を指し示しています。

### 単一部分のリクエスト

リソースから単一の範囲を要求することが可能です。ここで再び、cURL を用いてこれを検証することができます。"`-H`"オプションはリクエストに対して、この場合、最初の 1024 バイトを要求する`Range` ヘッダーラインを付け加えることができます。
```

curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"
```

発行されるリクエストは次のようになります:
```

GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023
```

サーバーは `206` `Partial Content` ステータスコードとともに以下のレスポンスを返します:
```

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
...
(binary content)
```

`Content-Length` はここでの場合、要求された範囲の大きさを返します(画像全体の大きさではありません)。 `Content-Range` レスポンスヘッダーはこの部分的なメッセージが全体のリソースのうちのどの部分に属しているのかを指し示しています。

### 複数部分のリクエスト

`Range` ヘッダーはまた、ドキュメントの複数の範囲を一度に取得する手段も提供しています。それら複数の範囲はカンマで区切ることで指定できます。
```

curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"
```

サーバーは `206` `Partial Content` ステータスコードと `Content-Type``: multipart/byteranges; boundary=3d6b6a416f9b5` ヘッダを伴ってレスポンスを返し、そこでは指定した複数のバイト範囲に関するデータが後ろに続いていることがわかります。 各々のバイト範囲において対応する `Content-Type` と `Content-Range` ヘッダーフィールドが含まれており、それぞれのボディ部分を区切るための境界文字列が境界パラメーターによって指定されています。
```

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 282

--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 0-50/1270

<!doctype html>
<html>
<head>
    <title>Example Do
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 100-150/1270

eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--
```

### 条件付き範囲リクエスト

リソースのさらなる部分に対してリクエストを再開する際、最後にバイト範囲の断片を受け取ったときから、サーバー側で格納されているリソースが変更されていないことを保証する必要があります。

`If-Range` HTTP リクエストヘッダは範囲リクエストに対して条件付けを付与することができます。条件が満たされた場合、範囲リクエストが発行され、サーバーは適切なボディとともに `206` `Partial Content` ステータスを返します。もし条件が満たされなかった場合、全てのリソースが `200` `OK` ステータスとともに返されます。このヘッダは `Last-Modified` validator あるいは `ETag` を伴って用いられます。両方を同時に使うことはありません。
```

If-Range: Wed, 21 Oct 2015 07:28:00 GMT
```

部分的なリクエストのレスポンス
---------------

範囲リクエストを用いる際、これに関連した３つのステータスコードが存在します。

* 範囲リクエストが成功した際 `206` `Partial Content` ステータスコードがサーバーから返されます。
* 範囲リクエストが元のリソースの境界を越え出た場合 (つまり範囲を示す値がリソースより外にはみ出た場合) 、サーバーは `416` `Requested Range Not Satisfiable` ステータスコードを返します。
* 範囲リクエストがサポートされていない場合、サーバーから `200` `OK` ステータスコードが返されます。
チャンク `Transfer-Encoding` との比較
-----------------------------

`Transfer-Encoding` ヘッダーを用いることでチャンクごとのエンコーディングが可能になります。これは大きいサイズのデータがクライアントに送られ、リクエストが完全に処理されるまでレスポンス全体のサイズが判明しない場合に有用です。サーバーはクライアントに対して、バッファリングも実際の大きさも確かめることなく、即座にデータを送ります。これはレイテンシーの向上に導きます。範囲リクエストとチャンクの使用は共用可能であり、互いに指定されていようといなかろうと気にせず使用することが可能です。

関連情報
----

* 関連するステータスコード `200`, `206`, `416`.
* 関連するヘッダー: `Accept-Ranges`, `Range`, `Content-Range`, `If-Range`, `Transfer-Encoding`.
* Download resumption in Internet Explorer


ユーザーエージェント文字列を用いたブラウザーの判定 - HTTP

ユーザーエージェント文字列を用いたブラウザーの判定
=========================

ブラウザーによって異なるウェブページまたはサービスを提供するのは、ふつうは良いことではありません。ウェブは使用しているブラウザーや機器に関係なく、誰からでもアクセスできるものです。ウェブサイトを開発する方法として、特定のブラウザーを対象にするのではなく、機能が利用できるかどうかに基づいたプログレッシブエンハンスメントにする方法があります。

しかし、ブラウザーや標準は完全ではなく、ブラウザーの判定を必要とする場合も稀にあります。ユーザーエージェント文字列を使用してブラウザーを判定することは簡単に見えますが、うまく行くようにするのは、実はとても難しい問題です。この文書では、これをできるだけ正しく行う方法を案内します。

**メモ:** 繰り返します。ユーザーエージェントを調べるのが良いことはめったにありません。問題を解決するには、もっと良い、もっと広く互換性のある方法が見つかるはずです。

ブラウザーの判定を用いる前に考えること
-------------------

ユーザーエージェント文字列を使用して、使用されているブラウザーを判定することを検討している場合は、できればまずは回避するようにしてください。**なぜ**それをやりたいのかを見分けることから始めましょう。

ブラウザーのあるバージョンの特有のバグを回避しようとしているのですか？

専門のフォーラムで見たり尋ねたりしてみましょう。この問題に最初に遭遇したのがあなたであることはほとんどありません。また専門家、あるいは別の視点を持つ人々が、バグを回避するためのアイディアをくれるかもしれません。珍しい問題である場合は、このバグがバグ追跡システム (Mozilla; WebKit; Blink; Opera) を介してブラウザーのベンダーに報告されているかどうかを確認することが重要です。ブラウザーメーカーはバグレポートに注意を払い、そのバグの他の回避策を分析するかもしれません。

特定の機能が存在するかどうか確認しようとしているのですか？

一部のブラウザーがまだ対応していない特定のウェブ機能をサイトで使用する必要がある場合、未対応のブラウザーのユーザーには、より機能が少ないものの動作することが分かっている古いウェブサイトを送信したい場合があります。これはユーザーエージェントの検出を使用する最悪の理由です。なぜなら、この差は最終的に他のすべてのブラウザーが追いつくからです。さらに、これらのウェブ機能について、それほど一般的でないブラウザーを１つ１つテストするのは現実的ではありません。ユーザーエージェントによる判定は**決して**行うべきではありません。その代わりに**常に**機能の検出を行う代替手段があります。

使用されているブラウザーによって異なる HTML を提供する予定ですか？

通常では悪い慣例ですが、これが必要な場合もあります。このような場合は、まず自分の状況を分析してそれが本当に必要であることを確認してください。形式的な `<div>` または `<span>` 要素を追加することで、それを防ぐことができませんか？ユーザーエージェントの検出を正しく行うことは、 HTML の純度をいくらか損なっても構わないくらい難しいものです。また、デザインを考え直してください。プログレッシブエンハンスメントや流体レイアウトを使用することで、回避することはできませんか？

ユーザーエージェントの判定の回避
----------------

ユーザーエージェントの検出を使用しないようにするのであれば、いくつかの選択肢があります。

機能の検出

機能の検出とは、ページを表示しているブラウザーを特定するのではなく、必要な機能が利用可能であるかどうかを確認することです。利用できない場合は代替手段を使用します。ブラウザーによって異なる動作をする場合は稀ですが、ユーザーエージェント文字列をチェックする代わりに、ブラウザーがその API をどう実装しているか検査する処理を実装し、そこから使い方を判断しましょう。機能の検出の今のところ良い例は次の通りです。最近、 Chrome は正規表現に実験的な後方参照の対応を追加しましたが、他のブラウザーは今のところ対応していません。ですから、間違って以下のようにするべきと思うかもしれません。

```js
// This code snippet splits a string in a special notation
let splitUpString;
if (navigator.userAgent.includes("Chrome")) {
  // YES! The user is suspected to support look-behind regexps
  // DO NOT USE /(?<=[A-Z])/. It will cause a syntax error in
  // browsers that do not support look-behind expressions
  // because all browsers parse the entire script, including
  // sections of the code that are never executed.
  const camelCaseExpression = new RegExp("(?<=[A-Z])");
  splitUpString = (str) => String(str).split(camelCaseExpression);
} else {
  // This fallback code is much less performant, but works
  splitUpString = (str) => str.replace(/[A-Z]/g, "z$1").split(/z(?=[A-Z])/g);
}

console.log(splitUpString("fooBare")); // ["fooB", "are"]
console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"]
```

 上記のコードでは、いくつかの間違った仮定をするでしょう。
 まず、部分文字列 "Chrome" を含むすべてのユーザーエージェント文字列が Chrome であると仮定するでしょう。 UA 文字列は誤解を招くことで有名です。
 そして、ブラウザーが Chrome であれば、 lookbehind 機能は常に利用可能であると仮定しています。エージェントは対応が追加される前の古いバージョンの Chrome かもしれないし、（当時は実験的な機能だったので）それが削除された後のバージョンの Chrome かもしれません。
 最も重要なのは、他のブラウザーがこの機能に対応していないことを前提としていることです。他のブラウザーではいつの間にか対応が追加されていたかもしれませんが、このコードでは劣った道を選択し続けることになります。

このような問題は、機能自体の対応をテストすることで回避することができます。

```js
let isLookBehindSupported = false;

try {
  new RegExp("(?<=)");
  isLookBehindSupported = true;
} catch (err) {
  // If the agent doesn't support look behinds, the attempted
  // creation of a RegExp object using that syntax throws and
  // isLookBehindSupported remains false.
}

const splitUpString = isLookBehindSupported
  ? (str) => String(str).split(new RegExp("(?<=[A-Z])"))
  : (str) => str.replace(/[A-Z]/g, "z$1").split(/z(?=[A-Z])/g);
```

上記のコードが示すように、ブラウザーの互換性をユーザーエージェントの判定なしに行う方法は**常に**あります。このためにユーザーの文字列をチェックする理由は**決してありません**。

最後に、上記のコードスニペットは、常に考慮しなければならないクロスブラウザーのコーディングで重大な問題を引き起こします。サポート対象外のブラウザーでテストしている API を意図せず使用しないでください。これは明らかでシンプルに聞こえるかもしれませんが、そうでない時もあります。たとえば、上記のコードスニペットでは、短い regexp 表記（たとえば /reg/igm）で lookbehind を使用すると、サポートされていないブラウザーで parser エラーが発生します。したがって、あなたのコードの lookbehind がサポートされているセクションであっても、上記の例では *new RegExp("(?<=look\_behind\_stuff)");* を */(?<=look\_behind\_stuff)/* の代わりに使用します。

プログレッシブエンハンスメント

この設計手法は、ウェブサイトを「階層」で開発し、ボトムアップのアプローチを使用して、より簡単な階層から始め、階層が上がるに従ってより多くの機能を使用して、サイトの機能を向上させる方法です。

グレイスフルデグラデーション

これはトップダウンのアプローチで、必要なすべての機能を使用して最適なサイトを構築し、それを古いブラウザーでも使用できるように調整する方法です。これは、プログレッシブエンハンスメントよりも難しく、有効性が低くなりますが、場合によっては有用であることがあります。

モバイル端末の検出

おそらく、ユーザーエージェントの判定で最も一般的かつ誤った使用法は、その端末がモバイル端末であるかどうかを検出することです。しかし、それが後で本当にどうなるかは見過ごされがちです。開発者はユーザーエージェントの判定を使用して、ユーザーの端末がタッチ操作であることや小さい画面であることを判別し、それに応じてウェブサイトを最適化することがあります。ユーザーエージェントの判定でこれらを検出できることもありますが、すべての端末が同じではありません。モバイル端末が大きなサイズの画面を持っている場合もあるし、デスクトップが小さなタッチ画面を持っている場合もあるし、まったく異なる球技であるスマートテレビで見ている場合もあるし、タブレットの向きを回転させて画面の幅や高さを動的に変化させている人もいます。よって、ユーザーエージェントの検出は決定的な方法ではありません。幸い、はるかに良い代替方法があります。ユーザーの端末にタッチ画面があるかどうかを検出するには、 Navigator.maxTouchPoints を使用しましょう。そして、 *if (!("maxTouchPoints" in navigator)) { /\*Code here\*/}* の場合のみ、ユーザーエージェントの画面をチェックする既定に戻します。この情報を使用して端末にタッチ画面があるかどうかを確認することができますが、タッチ端末であるだけのためにウェブサイトのレイアウト全体を変更しないようにしてください。これは自分の作業とメンテナンスの量を増やすだけです。それよりも、タッチに適したより大きい、よりクリックしやすいボタンを追加しましょう (CSS を使用してフォントを拡大することができます)。モバイル端末で #exampleButton のパディングを 1em に拡張するコードの例を示します。

```js
let hasTouchScreen = false;
if ("maxTouchPoints" in navigator) {
  hasTouchScreen = navigator.maxTouchPoints > 0;
} else if ("msMaxTouchPoints" in navigator) {
  hasTouchScreen = navigator.msMaxTouchPoints > 0;
} else {
  const mQ = matchMedia?.("(pointer:coarse)");
  if (mQ?.media === "(pointer:coarse)") {
    hasTouchScreen = !!mQ.matches;
  } else if ("orientation" in window) {
    hasTouchScreen = true; // deprecated, but good fallback
  } else {
    // Only as a last resort, fall back to user agent sniffing
    const UA = navigator.userAgent;
    hasTouchScreen =
      /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
      /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA);
  }
}

if (hasTouchScreen) {
  document.getElementById("exampleButton").style.padding = "1em";
}
```

画面のサイズについては、 *window.innerWidth* と window.addEventListener("resize", () => { /\*refresh screen size dependent things\*/ }) を使用してください。画面サイズの対策としてやりたいことは、小さな画面の時に情報を削らないことです。デスクトップバージョンを使用するようになるので、人々を悩ますだけです。むしろ、小さい画面で長いページでは情報の列数を少なくし、画面サイズが大きいほど短いページで多くの列を持つようにしてください。この効果は、 CSS フレックスボックスを使用し、時には部分的な代替手段として浮動レイアウトを用いることで簡単に達成できます。

また、関連性や重要性の低い情報を下に移動させ、ページのコンテンツを有意義にまとめてみてください。トピック外ではありますが、以下の詳細な例を見れば、ユーザーエージェントのスニッフィングを避けるための洞察力やアイデアが得られるかもしれません。複数の情報のボックスで構成されたページを想像してみましょう。それぞれのボックスは様々な猫や犬の品種についてのものであるとします。各ボックスには、画像、概要、経緯があるとします。画像は、大画面でも適切な最大の大きさが維持されるとします。意味のあるグループ分けをするために、すべての猫のボックスとすべての犬のボックスを分離し、猫と犬の箱が混在しないようにしています。大きな画面では、段組みをして画像の左右の無駄な空間を縮小することで、空間を節約します。このボックスは 2 つの等価な方法により、段組みに分割することができます。ここで、犬のボックスはすべてソースコードの上の方にあり、猫のボックスはすべてソースコードの下の方にあり、これらの箱の親要素はすべて共通であると仮定します。もちろん、猫ボックスのすぐ上に犬ボックスの単一のインスタンスがあります。最初の方法では、水平方向のフレックスボックスを使用してコンテンツをグループ化し、ページがエンドユーザーに表示されたときに、すべての犬のボックスをページの上部に配置し、すべての猫のボックスをページの下部に配置するようにします。2 つ目の方法は段組みレイアウトを使用し、すべての犬を左に、すべての猫を右に配置します。この特定のシナリオでのみ、フレックスボックス/段組みのフォールバックを提供しないことが適切であり、その結果、古いブラウザー上では非常に幅の広いボックスの単一の列になります。また、以下のことも考慮してください。より多くの人がウェブページに猫を見に来るのであれば、ソースコード上で犬よりも猫をすべて先に書くと、コンテンツが一段になるような小さな画面でも、より多くの人が探しているものをより早く見つけることができるようになるので、良い考えかもしれません。

 次に、コードを常に動的にしましょう。
 ユーザーは携帯端末の向きを回転させて、ページの幅と高さを変更することがあります。
 または、将来は広げると画面が拡張できるような、折り畳み式電話のような奇妙な端末が現れるかもしれません。
 折り畳み式電話のような端末をどのように扱うかということに頭を悩ませないでください。
 開発者ツールのサイドパネルを開いて画面のサイズを変更してみて、ウェブページが滑らかに、流動的に、動的にサイズ変更されるようになるまで満足しないようにしてください。
 これを行う最も単純な方法は、画面の大きさに基づいてコンテンツを移動させるすべてのコードを、ページが読み込まれたときと、その後の resize イベントのたびに呼び出される単一の関数に分離することです。もし、このレイアウト関数がページの新しいレイアウトを決定する前に多くの計算がある場合は、イベントリスナーが呼び出されないようにイベントリスナーをデバウンスすることを検討してください。
 また、メディアクエリーの `(max-width: 25em)`, `not all and (min-width: 25em)`, `(max-width: 24.99em)` の間には大きな違いがあることにも注意してください。 `(max-width: 25em)` は `(max-width: 25em)` を除外し、 `not all and (min-width: 25em)` は `(max-width: 25em)` を含みます。
 `(max-width: 24.99em)` は、 `not all and (min-width: 25em)` の哀れな人のバージョンです。`(max-width: 24.99em)` を使用しないでください。
 適切なメディアクエリーを選択し、対応する JavaScript の中で適切な >=, <=, >, < を選択すると、これらが混ざってしまいやすく、結果として、レイアウトが変更された画面サイズでウェブサイトを見てしまうことになるからです。
 そのため、レイアウト変更が適切に行われているかどうかを確認するために、レイアウト変更が行われている正確な幅/高さでウェブサイトを徹底的にテストしてください。

最適なユーザーエージェントの判定
----------------

ユーザーエージェントの判定のよりよい代替案をすべて検討したうえで、ユーザーエージェントの判定が適切で正当化される可能性のある場合がまだいくつかあります。

そのような場合のひとつに、端末にタッチパネルがあるかどうかを検出する際に、ユーザーエージェントの判定をフォールバックとして使用するというものがあります。詳細は モバイル端末の検出の節を参照してください。

もう一つの例として、自動更新されないブラウザーのバグを修正する場合があります。 Internet Explorer (Windows) と Webkit (iOS) がその好例です。バージョン 9 以前の Internet Explorer は、レンダリングのバグ、 CSS のバグ、 API のバグなど、信じられないほどの問題を抱えていました。しかし、バージョン 9 以前の Internet Explorer は特別な小さな ~~wasp~~ 例外だったため、利用可能なブラウザー固有の機能に基づいてブラウザーを検出するのは非常に簡単でした。 Webkit は、 Apple が iOS 上のすべてのブラウザーに内部的に Webkit を使用するように強制しているため、ユーザーは古い端末上でより良い、より更新されたブラウザーを取得する方法がありません。ほとんどのバグは検出できますが、バグによっては他よりも検出に手間がかかる場合があります。そのような場合は、ユーザーエージェント検出を使用してパフォーマンスを節約するのが有効です。たとえば、 Webkit 6 には端末の向きが変わると、ブラウザーが MediaQueryList リスナーを実行しない場合があるというバグがあります。このバグを回避するには、以下のコードを参照してください。

```js
const UA = navigator.userAgent;
const isWebkit =
  /\b(iPad|iPhone|iPod)\b/.test(UA) &&
  /WebKit/.test(UA) &&
  !/Edge/.test(UA) &&
  !window.MSStream;

let mediaQueryUpdated = true;
const mqL = [];

function whenMediaChanges() {
  mediaQueryUpdated = true;
}

const listenToMediaQuery = isWebkit
  ? (mQ, f) => {
      if (/height|width/.test(mQ.media)) {
        mqL.push([mQ, f]);
      }
      mQ.addListener(f);
      mQ.addListener(whenMediaChanges);
    }
  : () => {};

const destroyMediaQuery = isWebkit
  ? (mQ) => {
      for (let i = 0; i < mqL.length; i++) {
        if (mqL[i][0] === mQ) {
          mqL.splice(i, 1);
        }
      }
      mQ.removeListener(whenMediaChanges);
    }
  : listenToMediaQuery;

let orientationChanged = false;
addEventListener(
  "orientationchange",
  () => {
    orientationChanged = true;
  },
  PASSIVE\_LISTENER\_OPTION,
);

addEventListener("resize", () =>
  setTimeout(() => {
    if (orientationChanged && !mediaQueryUpdated) {
      for (let i = 0; i < mqL.length; i++) {
        mqL[i][1](mqL[i][0]);
      }
    }
    mediaQueryUpdated = orientationChanged = false;
  }, 0),
);
```

探している情報がユーザーエージェント文字列のどの部分に含まれているか
----------------------------------

ユーザーエージェント文字列のそれぞれの部分には統一性がないので、これは難しい部分です。

### ブラウザー名

開発者が「ブラウザーを判定したい」という場合、実際は「レンダリングエンジンを判定したい」場合であることがしばしばあります。実際に SeaMonkey と Firefox を、または Chromium と Chrome を区別したいのでしょうか。それとも、実際にはブラウザーがレンダリングエンジンに Gecko を使用しているか、 WebKit を使用しているかを確認したいのしょうか。これが必要なのであれば、ページのもっと下を見てください。

ほとんどのブラウザーは、 Internet Explorer の例外を除いて、名前とバージョンを *BrowserName/VersionNumber* の形式で設定します。しかし、ユーザーエージェント文字列はこのような形式の名前だけから成っている訳ではないので、ブラウザーの名前が分かるわけではなく、探している名前があるかどうかを確認することしかできません。しかし、ブラウザーによってはうそをつくこともあります。例えば Chrome は、 Chrome と Safari の両方の文字列を含みます。ですから Safari を判定するには、 Safari の文字列があって Chrome の文字列がないことを確認する必要がありますし、 Chromium は自分自身を Chrome と報告することがよくあり、 Seamonkey は自分自身を Firefox として報告することが時々あります。

また、 BrowserName に単純な正規表現を使用しないように注意してください。ユーザーエージェント文字列には、 Keyword/Value 構文以外の文字列も含まれています。例えば、 Safari や Chrome では、 'like Gecko' のような文字列が含まれています。

| エンジン | 必ず含む | 決して含まない |
| --- | --- | --- |
| Firefox | `Firefox/xyz` | `Seamonkey/xyz` |
| Seamonkey | `Seamonkey/xyz` |  |
| Chrome | `Chrome/xyz` | `Chromium/xyz` または `Edg.*/xyz` |
| Chromium | `Chromium/xyz` |  |
| Safari | `Safari/xyz` | `Chrome/xyz` または `Chromium/xyz` |
| Opera 15+ (Blink ベースのエンジン) | `OPR/xyz` |  |
| Opera 12- (Presto ベースのエンジン) | `Opera/xyz` |  |
| Internet Explorer 10- | `; MSIE xyz;` |  |
| Internet Explorer 11 | `Trident/7.0; .*rv:xyz` |  |

[1] Safari はバージョン番号を 2 つ提供しており、一方は技術的な Safari/xyz のトークン、もう一方はユーザーに分かりやすい Version/xyz のトークンです。

もちろん、他のブラウザーがこれらの一部をハイジャックしないという絶対的な保証はありません（過去に Chrome が Safari の文字列をハイジャックしたように）。そのため、ユーザーエージェント文字列を使用したブラウザーの判定は信頼性が低いので、バージョン番号をチェックするのみにしてください（過去のバージョンをハイジャックすることはあまりありません）。

### ブラウザーのバージョン

ブラウザーのバージョンは、例外はあるものの、多くがユーザーエージェント文字列の *BrowserName/VersionNumber* トークンの値の部分に入れられます。もちろんこれは Internet Explorer の場合は当てはまらず（MSIE トークンの直後にバージョン番号を入れる）、 Opera のバージョン 10 以降では、 Version/*VersionNumber* トークンが追加されています。

ここで再度、探しているブラウザーの正しいトークンを取得していることを確認してください。他には妥当な番号が含まれているという保証はありません。

### レンダリングエンジン

前述のように、多くの場合はレンダリングエンジンを探した方が良い方法になります。これは、あまり知られていないブラウザーを除外しないためにも役立つでしょう。共通のレンダリングエンジンを持つブラウザーはページを同じ方法で表示します。一方で動作するものはもう一方でも動作するということを想定することができます。

主なレンダリングエンジンには、 Trident, Gecko, Presto, Blink, WebKit の 5 つがあります。レンダリングエンジンの名前を探すのが一般的であるため、たくさんのレンダリングエンジンが他のレンダリングエンジンの名前も追加して検出されるようにしています。したがって、レンダリングエンジンを判定する際には誤判定をしないように注意を払うことが重要です。

| エンジン | 必ず含む | コメント |
| --- | --- | --- |
| Gecko | `Gecko/xyz` |  |
| WebKit | `AppleWebKit/xyz` | 注意: WebKit ブラウザーは 'like Gecko' の文字列を追加するので、判定時に注意しないと Gecko と誤認することがあります。 |
| Presto | `Opera/xyz` | **メモ:** Presto は Opera ブラウザーのバージョン 15 以降では使用されない ('Blink' を参照) |
| Trident | `Trident/xyz` | Internet Explorer はこのトークンをユーザーエージェント文字列の*コメント*部分に入れる |
| EdgeHTML | `Edge/xyz` | Chromium ではない Edge は、 *Edge/* のトークンの後にアプリケーションのバージョンではなく、エンジンのバージョンを入れる。 **注:** EdgeHTML は Edge ブラウザーのバージョン 79 以降では使用されない ('Blink' を参照)。 |
| Blink | `Chrome/xyz` |  |

レンダリングエンジンのバージョン
----------------

ほとんどのレンダリングエンジンは、 Gecko を除いて *RenderingEngine/VersionNumber* のトークンにバージョン番号を入れています。 Gecko はユーザーエージェント文字列のコメント部分の中で、 `rv:` 文字列の後にバージョン番号を入れます。モバイル版の Gecko 14 とデスクトップ版の Gecko 17 から、この値を `Gecko/version` のトークン (以前のバージョンではビルド日付、その後は GeckoTrail と呼ばれる固定日付) に置きます。

OS
--

オペレーティングシステムは、多くのユーザーエージェント文字列で提供されますが (ただし Firefox OS のようなウェブ用のプラットフォームでは提供されません)、書式は大幅に異なります。これはユーザーエージェント文字列のコメント部分にある 2 つのセミコロン間の固定文字列です。これらの文字列はブラウザーに依存します。これは OS を示しますが、しばしばバージョンや依存するハードウェア (32/64 ビットや、 Mac の場合の Intel / PPC) も示します。

すべての場合と同様に、これらの文字列は将来変更される可能性があり、既にリリースされているブラウザーの判定と組み合わせて使用する必要があります。新しいバージョンのブラウザーが出現したときは、スクリプトを適合させるための技術調査が必要です。

### モバイルか、タブレットか、デスクトップか

ユーザーエージェントの判別を行う最も一般的な理由は、ブラウザーが実行されている端末の種類を判別することです。目的は、それぞれの種類の端末に別々な HTML を提供することです。

* ブラウザーやレンダリングエンジンは、1 種類の端末でしか動作しないと想定しないでください。ブラウザーやレンダリングエンジンごとに、異なる既定値を設定しないでください。
* ブラウザーがモバイル、タブレット、デスクトップのいずれであるかを定義するために、 OS トークンを使用しないでください。 OS は複数の種類の端末 (Android はタブレットや携帯電話など) で動作します。

次の表は主要なブラウザーのベンダーが、ブラウザーがモバイル端末上で動作していることを示す方法をまとめたものです。

| ブラウザー | ルール | 例 |
| --- | --- | --- |
| Mozilla (Gecko, Firefox) | `Mobile` または `Tablet` のトークンがコメントの中にある。 | Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0 |
| WebKit ベースのもの (Android, Safari) | `Mobile Safari` のトークンがコメントの外にある。 | Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 |
| Blink ベースのもの (Chromium, Google Chrome, Opera 15 以降) | `Mobile Safari` のトークンがコメントの外にある。 | Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047 |
| Presto ベースのもの (Opera 12 まで) | `Opera Mobi/xyz` のトークンがコメントの中にある。 | Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50 |
| Internet Explorer | `IEMobile/xyz` のトークンがコメントの中にある。 | Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0) |
| Edge on Windows 10 Mobile | `Mobile/xyz` および `Edge/` のトークンがコメントの外にある。 | Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Mobile Safari/537.36 Edge/16.16299 |

要するに、モバイル端末を検出するには、ユーザーエージェント文字列のどこかに文字列 `Mobi` があるかどうかを探すことをお勧めします。

**メモ:** 端末が大きくて `Mobi` と表示されていない場合は、デスクトップサイトを提供してください（ベストプラクティスとして、デスクトップ機にタッチ画面が採用されつつあるので、どちらにしてもタッチ入力に対応するようにしてください）。


既定の Accept 値の一覧 - HTTP

既定の Accept 値の一覧
===============

この記事では、特定の入力とブラウザーのバージョンにおける HTTP の `Accept` ヘッダーの既定値について説明します。

既定値
---

これらは、コンテキストから良い情報が得られない場合に送信される値です。なお、すべてのブラウザーがすべての場合をカバーするために `*/*` MIME タイプを追加します。これは通常、ブラウザーのアドレスバーを介して開始されるリクエスト、または HTML の `<a>` 要素を介して開始されるリクエストに使用されます。

| ユーザーエージェント | 値 |
| --- | --- |
| Firefox 92 以降 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8` |
| Firefox 72 ～ 91 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8` |
| Firefox 66 ～ 71 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` |
| Firefox 65 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8` |
| Firefox 64 以前 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` |
| Safari, Chrome | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8` |
| Safari 5 [2] | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` |
| Internet Explorer 8 [3] | `image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */*` |
| Edge | `text/html, application/xhtml+xml, image/jxr, */*` |
| Opera | `text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1` |

[1] この値は `network.http.accept.default` 設定値を使用して変更することができます。

[2] これは以前の `Accept` ヘッダーと比べて、 `image/png` を `text/html` より上にランク付けしなくなった点で改良されています。

[3] IE and the Accept Header (IEInternals' MSDN blog) を参照。

画像の値
----

ユーザエージェントは HTML の `<img>` 要素などを通して画像をリクエストするときに、しばしば歓迎されるメディア種別のリストを設定します。

| ユーザーエージェント | 値 |
| --- | --- |
| Firefox 92 以降 [1] | `image/avif,image/webp,*/*` |
| Firefox 65 ～ 91 [1] | `image/webp,*/*` |
| Firefox 47 ～ 63 [1] | `*/*` |
| Firefox 47 以前 [1] | `image/png,image/*;q=0.8,*/*;q=0.5` |
| Safari (Mac OS Big Sur 以降) | `image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5` |
| Safari (Mac OS Big Sur 以前) | `image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5` |
| Chrome | `image/avif,image/webp,image/apng,image/*,*/*;q=0.8` |
| Internet Explorer 9 | `image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5` |
| Internet Explorer 8 以前 *情報源* | `*/*` |

[1] この値は `image.http.accept` 設定値を使用して変更することができます (*情報源*).

動画の値
----

HTML の `<video>` 要素を介して動画をリクエストする際、ほとんどのブラウザーは特定の値を使用します。

| ユーザーエージェント | 値 |
| --- | --- |
| Firefox 3.6 以降 | `video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5` |
| Firefox 3.6 以前 | *`<video>` に未対応* |
| Chrome | `*/*` |
| Internet Explorer 8 以前 | *`<video>` に未対応* |

音声リソースの値
--------

HTML の `<audio>` 要素などを使用して音声ファイルをリクエストする際、ほとんどのブラウザーは特定の値を使用します。

| ユーザーエージェント | 値 |
| --- | --- |
| Firefox 3.6 以降 [1] | `audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5` |
| Safari, Chrome | `*/*` |
| Internet Explorer 8 以前 | *`<audio>` に未対応* |
| Internet Explorer 9 | ? |

[1] bug 489071 を参照。

スクリプトの値
-------

HTML の `<script>` 要素などを通してスクリプトをリクエストする際、ブラウザーによっては特定の値を使用します。

| ユーザーエージェント | 値 |
| --- | --- |
| Firefox [1] | `*/*` |
| Safari, Chrome | `*/*` |
| Internet Explorer 8 以前 [2] | `*/*` |
| Internet Explorer 9 | `application/javascript, */*;q=0.8` |

[1] bug 170789 を参照。

[2] IE and the Accept Header (IEInternals' MSDN blog) を参照。

CSS スタイルシートの値
-------------

HTML の `<link rel="stylesheet">` 要素を使用して CSS スタイルシートをリクエストする際、ほとんどのブラウザーは特定の値を使用します。

| ユーザーエージェント | 値 |
| --- | --- |
| Firefox 4 [1] | `text/css,*/*;q=0.1` |
| Internet Explorer 8 以前 [2] | `*/*` |
| Internet Explorer 9 | `text/css` |
| Safari, Chrome | `text/css,*/*;q=0.1` |
| Opera 11.10 | `text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1` |
| Konqueror 4.6 | `text/css,*/*;q=0.1` |

[1] bug 170789 を参照。

[2] IE and the Accept Header (IEInternals' MSDN blog) を参照。


Content-Security-Policy - HTTP

Content-Security-Policy
=======================

HTTP の **`Content-Security-Policy`** レスポンスヘッダーは、ウェブサイト管理者が、あるページにユーザーエージェントが読み込みを許可されたリソースを管理できるようにします。いくつかの例外を除いて、大半のポリシーにはサーバーオリジンとスクリプトエンドポイントの指定を含んでいます。これはクロスサイトスクリプティング攻撃 (クロスサイトスクリプティング) を防ぐのに役立ちます。

より詳細な情報は、Content Security Policy (CSP) の入門記事を参照してください。

|  |  |
| --- | --- |
| ヘッダー種別 | レスポンスヘッダー |
| 禁止ヘッダー名 | いいえ |

構文
--

```http
Content-Security-Policy: <policy-directive>; <policy-directive>
```

ここで、 `<policy-directive>` は `<directive> <value>` の形であり、内部に区切り文字はありません。

ディレクティブ
-------

### フェッチディレクティブ

フェッチディレクティブは、特定のリソース種別を読み込むことができる場所を制御します。

`child-src`

ウェブワーカーと、`<frame>` や `<iframe>` のような要素によって読み込まれる入れ子の閲覧コンテキストのための有効なソースを定義します。

**警告:** 複合した閲覧コンテキストやワーカーを制御するには、 **`child-src`** の代わりに、それぞれ `frame-src` および `worker-src` を使用してください。

`connect-src`

スクリプトインターフェイスによって読み込まれる URL を制限します。

`default-src`

別の Fetch ディレクティブに対する代替として提供します。

`font-src`

`@font-face` によって読み込まれるフォントのための有効なソースを指定します。

`frame-src`

`<frame>` や `<iframe>` のような要素によって読み込まれる入れ子のコンテンツの閲覧のための有効なソースを指定します。

`img-src`

画像やファビコンのための有効なソースを定義します。

`manifest-src`

アプリケーションのマニフェストファイルのための有効なソースを指定します。

`media-src`

`<audio>`、`<video>`、`<track>` 要素によって読み込むメディアのための有効なソースを指定します。

`object-src`

`<object>`、 `<embed>`、`<applet>` 要素のための有効なソースを指定します。

**メモ:** `object-src` で制御される要素は、おそらく古い HTML 要素に該当すると見なされ、標準化された新しい機能が利用できません（セキュリティ属性の `sandbox` や `<iframe>` の `allow` など）。従って、このフェッチディレクティブで制限を掛けることが**推奨されます** （例えば、可能であれば `object-src 'none'` を設定するなど）。

`prefetch-src`
Experimental

事前にフェッチされるか描画される有効なソースを指定します。

`script-src`

JavaScript および WebAssembly のための有効なソースを指定します。

`script-src-elem`

JavaScript の `<script>` 要素のための有効なソースを指定します。

`script-src-attr`

JavaScript のインラインイベントハンドラーのための有効なソースを指定します。

`style-src`

スタイルシートのための有効なソースを指定します。

`style-src-elem`

スタイルシートの `<style>` および `<link>` 要素に `rel="stylesheet"` がついたものののための有効なソースを指定します。

`style-src-attr`

個々の DOM 要素に適用されるインラインスタイルの有効なソースを指定します。

`worker-src`

`Worker`、`SharedWorker`、`ServiceWorker` スクリプトのための有効なソースを指定します。

### 文書ディレクティブ

文書ディレクティブは、ポリシーが適用される文書またはワーカー環境のプロパティを管理します。

`base-uri`

文書の `<base>` 要素で使用される URL を制限します。

`sandbox`

`<iframe>` と `sandbox` 属性に類似した要求リソースに対してサンドボックスを有効にします。

### ナビゲーションディレクティブ

ナビゲーションディレクティブは、例えばユーザーが移動する場所やフォームを送信する場所を管理します。

`form-action`

指定のコンテキストからフォームの送信先として使用される URL を制限します。

`frame-ancestors`

`<frame>`、`<iframe>`、`<object>`、`<embed>`、`<applet>` によってページに埋め込まれた有効な親を指定します。

`navigate-to` (en-US)
Experimental

`<form>` (`form-action` が指定されていない場合)、`<a>`、`window.location`、`window.open` など、あらゆる方法で文書からナビゲーションを行うことができる URL を制限します。

### 報告ディレクティブ

報告ディレクティブは CSP 違反の報告過程を制御します。 `Content-Security-Policy-Report-Only` ヘッダーも参照してください。

`report-uri`
非推奨

ユーザーエージェントにコンテンツセキュリティポリシーの違反を報告するよう指示します。これらの違反の報告は、 JSON 文書を HTTP の `POST` リクエストで指定された URI に送信することで行われます。

**警告:** `report-to` ディレクティブは非推奨の **`report-uri`** ディレクティブを置き換えることを意図していますが、 `report-to` はまだ多くのブラウザーが対応していません。そのため、ブラウザーで `report-to` の対応が行われるまでは、現在のブラウザーとの互換性のため、 **`report-uri`** と `report-to` の両方を指定することができます。

```http
Content-Security-Policy: …; report-uri https://endpoint.example.com; report-to groupname
```

`report-to` に対応しているブラウザーでは、 **`report-uri`** ディレクティブは無視されます。

`report-to`

`SecurityPolicyViolationEvent` を発生させます。

### その他のディレクティブ

`require-trusted-types-for`
Experimental

DOM XSS インジェクションシンクで Trusted
Types を強制します。

`trusted-types`
Experimental

Trusted Types ポリシーのホワイトリストを指定するために使用します (Trusted Types は、アプリケーションが DOM XSS インジェクションシンクをロックダウンして、文字列の代わりにスプーフィング不可能な型付きの値のみを受け入れるようにします)。

`upgrade-insecure-requests`

安全でない URL (HTTP で提供されているもの) をすべて安全な URL (HTTPS で提供されているもの) に置き換えたかのように扱うようにユーザエージェントに指示します。このディレクティブは、書き換えが必要な安全でない古い URL が大量にあるウェブサイトを対象としています。

### 非推奨のディレクティブ

`block-all-mixed-content`
非推奨

ページが HTTPS を使用して読み込まれた際に、 HTTP を使用して資産を読み込むことを防止します。

`plugin-types`
非推奨

Non-standard

読み込まれるリソースの種類を限定することで、文書に埋め込まれるプラグインの組を制限します。

`referrer`
非推奨

Non-standard

ページから離れる際の Referer (綴り注意) ヘッダー内の情報を指定するために使用されていました。代わりに `Referrer-Policy` ヘッダーを使用してください。

値
-

 許可さ れている値の概要を以下に示します。
 詳細な参照は、CSP ソース値 および各ディレクティブのドキュメントを参照してください。

### キーワード値

`'none'`

すべてのリソースの読み込みを許可しません。

`'self'`

現在のオリジンからのみリソースの読み込みを許可します。

`'strict-dynamic'`

ページ内のスクリプトに付随する nonce やハッシュによって与えられた信頼は、それが読み込むスクリプトに拡張されます。

`'report-sample'`

違反したコードのサンプルを違反レポートに含めて記載することを要求する。

### unsafe キーワード値

`'unsafe-inline'`

インラインリソースの使用を許可します。

`'unsafe-eval'`

`eval` や `setImmediate` (en-US)
Non-standard
、`window.execScript`
Non-standard
 のような動的コード評価の使用を許可します。

`'unsafe-hashes'`

特定のインラインイベントハンドラーを有効にすることができます。

`'unsafe-allow-redirects'`
Experimental

TBD

### ホスト値

* Host
    + 指定されたホストからのリソースの読み込みのみを許可します。オプションでスキーム、ポート番号、パスを指定することができます。例えば、 `example.com`, `*.example.com`, `https://*.example.com:12/path/to/file.js` などです。
    + CSP 内の `/` で終わるパス部分は、その接頭辞であるすべてのパスに一致します。例えば、`example.com/api/` は `example.com/api/users/new` のような URL に一致します。
    + CSP の他のパス属性の部分は正確に照合されます。例えば、`example.com/file.js` は `http://example.com/file.js` と `https://example.com/file.js` には一致しますが、`https://example.com/file.js/file2.js` に一致するわけではありません。
* Scheme
    + 特定のスキームによるリソースの読み込みのみを許可します。常に "`:`" で終える必要があります。例: `https:`, `http:`, `data:` など
### その他の値

`'nonce-*'`

スクリプトを許可するための暗号化された (一度しか使われない) ノンスです。サーバーは、ポリシーを送信するたびに、一意のノンス値を生成する必要があります。リソースのポリシーを迂回することは容易ではないため、推測されないノンスを提供することが重要です。これは script の nonce 属性と組み合わせて使用します。例えば、 `nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV`

`'sha*-*'`

sha256、sha384、sha512 のいずれかです。その後にダッシュと sha\* の値が続きます。例: `sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY=`

ワーカー内の CSP
----------

ワーカーは、一般的に文書 (もしくは親ワーカー) のコンテンツセキュリティポリシーによって管理され*ません*。ワーカーに対してコンテンツセキュリティポリシーを指定するには、ワーカースクリプト自身が要求したリクエストに対して `Content-Security-Policy` レスポンスヘッダーを設定して下さい。

ワーカースクリプトのオリジンがグローバルで一意の識別子の場合 (例えば、URL がデータやブロブのスキーマの場合) は例外です。この場合、ワーカーは文書もしくは作成元のワーカーのコンテンツセキュリティポリシーを継承します。

複数の CSP
-------

CSP では、`Content-Security-Policy` ヘッダー、`Content-Security-Policy-Report-Only` ヘッダーや `<meta>` 要素を経由したものを含む、リソースに対して複数のポリシーを指定することができます。

以下の例のように、 `Content-Security-Policy` ヘッダーを複数回使うことができます。ここでは `connect-src` ディレクティブに特に注意してください。 2 つ目のポリシーでは接続を許可しているにもかかわらず、 1 つ目のポリシーには `connect-src 'none'` が含まれています。追加のポリシーを追加しても、保護されたリソースの機能が*さらに制限することができる*だけで、接続は許可されず、最も厳密なポリシーとして `connect-src 'none'` が強制されます。

```http
Content-Security-Policy: default-src 'self' http://example.com;
 connect-src 'none';
Content-Security-Policy: connect-src http://example.com/;
 script-src http://example.com/
```

例
-

例: 安全でないインラインの eval を無効にし、https 経由でのリソース (画像、フォント、スクリプトなど) 読み込みを許可します。

### HTTP ヘッダーの使用

```http
Content-Security-Policy: default-src https:
```

### HTML の meta 要素の使用

```html
<meta http-equiv="Content-Security-Policy" content="default-src https:" />
```

例: 修正のためにインラインコードを多用している既存のサイトで、https 経由でのみ読み込まれるリソースを明確にし、プラグインを無効にします。

```http
Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'
```

例: 上記のポリシーを実装せず、代わりに、発生するであろう違反を報告します。

```http
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/
```

その他の例は、Mozilla Web Security Guidelines を参照して下さい。

仕様書
---

| Specification |
| --- |
| Content Security Policy Level 3 # csp-header |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `Content-Security-Policy-Report-Only`
* コンテンツセキュリティポリシーを学ぶ
* WebExtension のコンテンツセキュリティ
* Adopting a strict policy
* CSP Evaluator - コンテンツセキュリティポリシーを評価する