1. ホーム
  2. HTML

【HTML】referrerpolicy 属性の使い方|リファラーの送信範囲を制御する方法

Share

リンクをクリックしたり画像を読み込んだりすると、ブラウザーは移動先のサーバーに「どのページから来たか」を Referer(リファラー)ヘッダーとして伝えています。便利な仕組みですが、URL の中に社内向けのパスや検索条件が入っていると、それがそのまま外部に渡ってしまうこともあります。この記事では、リファラーの送信範囲を制御する referrerpolicy 属性について、指定できる要素、8つのポリシー値で実際に何が送られるか、<meta name="referrer"> や HTTP ヘッダーとの優先順位までを解説します。

リファラーは「どのページから来たか」を伝えるヘッダー

ブラウザーがサーバーにリクエストを送るとき、そのリクエストのきっかけになったページの URL を Referer という HTTP ヘッダーに入れて一緒に送ります。https://example.com/page?id=1 に置かれたリンクをたどって別のサイトへ移動すると、移動先のサーバーには次のようなヘッダーが届きます。

リクエストヘッダー
GET /welcome HTTP/1.1
Host: other.example
Referer: https://example.com/page?id=1

ちなみに Referer という綴りは、本来の英単語 referrer から r が1つ抜けた誤記です。初期の HTTP 仕様で綴りを間違えたまま広まってしまったため、ヘッダー名だけは今も Referer、HTML の属性や JavaScript のプロパティは正しい綴りの referrerpolicy / referrerPolicy という、ややこしい状態になっています。

送られるのはリンクのクリックだけではありません。ページ内の画像・スクリプト・スタイルシートの読み込みや、<iframe> の中身の取得など、ブラウザーが行うほとんどのリクエストにリファラーが付きます。なお、URL のうちフラグメント(# より後ろ)と、URL に埋め込まれたユーザー名・パスワードは、リファラーに入る前に必ず取り除かれます。

受け取る側にとっては、アクセス解析で流入元を知るための大切な情報です。「検索エンジンから来たのか、SNS から来たのか、どのサイトに紹介されたのか」が分かるのは、このヘッダーのおかげです。一方で、送る側から見ると自分のページの URL を相手に教えていることになります。

リファラーを制御したくなる場面

URL は、それ自体が情報を持っていることがあります。たとえば社内ツールの https://intranet.example.com/projects/2026-renewal/budget のような URL は、パスを見ただけで「どんなプロジェクトが動いているか」が伝わってしまいます。このページから外部のサイトへリンクを張れば、リンク先のアクセスログにこの URL がそのまま残ります。

クエリー文字列はさらに注意が必要です。検索結果ページの ?q= に入力したキーワード、フォームの入力内容を引き継ぐパラメーター、パスワード再設定メールに含まれるワンタイムトークンなど、外に出したくない値が URL に載っている場面は珍しくありません。こうしたページから外部リソースを読み込んだりリンクをたどったりすると、値ごと相手に渡ります。

とはいえ、リファラーを全部止めてしまえばよいという話でもありません。自分がリンクを送る側になったとき、相手のアクセス解析に「どこから来たか」が残らないと、紹介元として認識されなくなります。提携先や自社の別サービスへ送客しているなら、そこは残したいはずです。そのため実務では「詳しい URL は渡さないが、どのサイトから来たかは分かる」という中間の設定がよく選ばれます。

逆に、受け取る側の立場でリファラーを信頼しすぎないことも大切です。Referer ヘッダーは送信側が自由に変えられるうえ、この記事で扱う設定で簡単に消せます。アクセス解析の参考にはなっても、「特定のサイトから来た人だけを通す」といった認証の代わりには使えません。

referrerpolicy 属性を書ける要素

referrerpolicy は、その要素が発生させるリクエストに対してだけリファラーの送信範囲を指定する属性です。指定できるのは次の6つの要素です。

要素制御されるリクエスト
<a>リンクをたどったときの移動先へのリクエスト
<area>イメージマップの領域から移動するときのリクエスト
<img>画像ファイルの取得
<iframe>フレーム内に読み込む文書の取得
<link>スタイルシートや先読みリソースの取得
<script>外部 JavaScript ファイルの取得

書き方はどの要素でも同じで、属性の値にポリシー名を1つ書くだけです。

index.html
<!-- このリンクだけリファラーを送らない -->
<a href="https://other.example/" referrerpolicy="no-referrer">外部サイト</a>

<!-- この画像の取得ではオリジンだけを送る -->
<img src="https://cdn.example/photo.jpg" alt="写真" referrerpolicy="origin">

<!-- 埋め込みフレームにはページの URL を渡さない -->
<iframe src="https://widget.example/embed" referrerpolicy="no-referrer" title="ウィジェット"></iframe>

<!-- 外部スクリプトの取得でもオリジンまでに絞る -->
<script src="https://cdn.example/lib.js" referrerpolicy="strict-origin"></script>

指定した値が無効だったとき(綴りの間違いなど)は、その属性は無視され、ページ全体の設定やブラウザーの既定値が使われます。エラーにはならず静かに無視されるので、意図どおりに効いているかは実際の通信で確かめるのが確実です。

8つのポリシー値で何が送られるか

指定できる値は8つあります。違いを見分けるポイントは「同一オリジンか、別オリジンか」と「HTTPS から HTTP へ下がるか」の2つです。移動元を https://example.com/page?id=1 として、それぞれの値で何が送られるかを並べたのが次の表です。

値同一オリジンへ
(https://example.com/other)
別オリジンの HTTPS へ
(https://other.example/)
HTTP へ
(http://other.example/)
no-referrer送らない送らない送らない
no-referrer-when-downgradehttps://example.com/page?id=1https://example.com/page?id=1送らない
originhttps://example.com/https://example.com/https://example.com/
origin-when-cross-originhttps://example.com/page?id=1https://example.com/https://example.com/
same-originhttps://example.com/page?id=1送らない送らない
strict-originhttps://example.com/https://example.com/送らない
strict-origin-when-cross-origin
(既定値)
https://example.com/page?id=1https://example.com/送らない
unsafe-urlhttps://example.com/page?id=1https://example.com/page?id=1https://example.com/page?id=1

表の「https://example.com/」という表記はオリジンだけ、つまりスキーム(https)・ホスト名・ポート番号のみを送るという意味です。パスの /page もクエリーの ?id=1 も含まれません。名前に付く語の意味をつかむと覚えやすくなります。origin が付けばオリジンだけ、strict が付けば HTTPS から HTTP へ下がるときは送らない、cross-origin が付けば別オリジンのときだけ絞る、という具合です。

何も送らない no-referrer と、常に全部送る unsafe-url

no-referrer は最も単純で、どんな相手に対しても Referer ヘッダー自体を付けません。トークン付きの URL を持つページや、社内システムの管理画面のように「何も渡したくない」場面に向いています。ただしリンク先の解析には自サイトが一切現れなくなるので、送客したいリンクに付けるかどうかは分けて考えてください。

反対の極にあるのが unsafe-url で、相手が誰であっても、HTTPS から HTTP への移動であっても、クエリー文字列まで含めたフル URL を送ります。名前のとおり安全ではない選択で、暗号化されたページの URL が暗号化されていない通信に流れ出す可能性があります。特別な理由がない限り使わないでください。

オリジンだけを送る origin と strict-origin

どちらも「自サイトのトップページの URL だけを伝える」という挙動で、パスやクエリーは渡しません。リンク先のアクセス解析には example.com からの流入 として記録されるので、詳細を隠しつつ流入元としては認識されます。

2つの違いは、HTTPS のページから HTTP のページへ移動するときの扱いです。origin はその場合でもオリジンを送りますが、strict-origin は送りません。暗号化されていない通信に情報を出さないという点で、strict-origin のほうが安全です。同一オリジンへの遷移でもパスを渡さないので、自サイト内の解析でリファラーを見ている場合は影響が出ることに注意してください。

自サイト内だけ詳しく送る same-origin 系の3つ

same-origin・origin-when-cross-origin・strict-origin-when-cross-origin の3つは、同一オリジンへのリクエストではフル URL を送り、別オリジンに対してだけ扱いを変えるグループです。自サイト内の導線を追いながら、外部には詳細を渡さない、という使い分けができます。

別オリジンのときの振る舞いが三者三様で、same-origin は何も送らず、origin-when-cross-origin はオリジンを送り、strict-origin-when-cross-origin はオリジンを送るが HTTPS から HTTP へ下がるときだけ送りません。外部への情報を完全に断ちたいなら same-origin、流入元としては認識されたいなら残りの2つ、という選び方になります。

いまの既定値は strict-origin-when-cross-origin

ポリシーを何も指定しなかったとき、あるいは無効な値を書いてしまったときに使われる既定値が strict-origin-when-cross-origin です。2020年の仕様改訂で定められたもので、現在の主要なブラウザーはこの値で動作しています。それ以前の既定値は no-referrer-when-downgrade、つまり HTTPS 同士なら外部にもフル URL を送る挙動でした。

この変更は、日々の開発にも影響しています。「以前は外部サイトのアクセス解析にページ単位の URL が出ていたのに、いまはドメインまでしか出ない」というのは、多くの場合この既定値の変更によるものです。裏を返せば、何も設定しなくても、外部へクエリー付きの URL が漏れることは既に防がれているということでもあります。現在 referrerpolicy を書く意味は、この既定値よりさらに絞りたいとき(no-referrer や same-origin)か、特定の相手にだけ緩めたいときに絞られます。

ページ全体にまとめて指定する meta name=”referrer”

要素ごとに属性を書くのが大変な場合は、<head> 内に <meta name="referrer"> を置くと、その文書から出るすべてのリクエストに同じポリシーが適用されます。値には referrerpolicy 属性と同じ8つの名前が使えます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <!-- このページ全体で、リファラーはオリジンまでに絞る -->
  <meta name="referrer" content="strict-origin">
  <title>サンプル</title>
</head>
<body>
  <!-- ページ設定は strict-origin だが、このリンクだけ何も送らない -->
  <a href="https://other.example/" referrerpolicy="no-referrer">外部サイト</a>
</body>
</html>

この <meta> は HTML が解析された時点で文書のポリシーを設定するため、できるだけ <head> の早い位置、少なくとも画像やスクリプトの読み込みより前に書きます。ページの後ろのほうに置くと、それより先に始まったリクエストには間に合いません。

綴りで引っかかりやすいのがハイフンの有無です。<meta> や referrerpolicy 属性で使うポリシー名はハイフン付きの no-referrer、後述する rel 属性のキーワードはハイフンなしの noreferrer です。どちらも「リファラーを送らない」ための指定なのに書き方が違うので、混同しないようにしてください。

HTTP ヘッダーで指定する方法と優先順位

HTML を触らずにサイト全体へ適用したいときは、サーバー側で Referrer-Policy レスポンスヘッダーを返す方法があります。.htaccess なら次のように書きます。

.htaccess
<IfModule mod_headers.c>
  Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

ヘッダーにはもう1つ、HTML 側にはない特徴があります。カンマ区切りで複数の値を並べると、ブラウザーが解釈できた最後の値が採用されるため、新しいポリシー値に対応していない環境へのフォールバックを用意できます。この書き方が使えるのはヘッダーだけで、referrerpolicy 属性や <meta> では複数指定できません。

レスポンスヘッダー
# 後ろの値を解釈できない環境では、前の no-referrer が使われる
Referrer-Policy: no-referrer, strict-origin-when-cross-origin

指定方法が3つあると、どれが勝つのかが気になります。考え方は単純で、「その文書全体のポリシー」がまずヘッダーと <meta> で決まり、個々の要素の referrerpolicy 属性がそれを上書きするという2段構えです。

文書全体のポリシーは、まずレスポンスの Referrer-Policy ヘッダーで設定されます。その後 HTML が解析されて <meta name="referrer"> が見つかると、その値で文書のポリシーが設定し直されます。つまり両方を書いた場合、ページに書いた <meta> の指定が後から効くことになります。サーバー側でサイト共通のポリシーを設定しておき、特定のページだけ <meta> で変える、という運用ができるわけです。

そして個々のリクエストについては、要素に referrerpolicy 属性があればそれが最優先で使われます。属性がなければ文書のポリシー、文書にも指定がなければブラウザーの既定値である strict-origin-when-cross-origin、という順に適用先が決まります。

rel=”noreferrer” とはどう違うのか

リンクからリファラーを消す方法としては、rel="noreferrer" のほうを見かけることが多いかもしれません。これは <a>・<area>・<form> で使えるキーワードで、移動先へのリクエストから Referer ヘッダーを省かせます。この点だけを見れば referrerpolicy="no-referrer" と同じ結果になります。

違いは2つあります。1つ目は効果の範囲です。rel="noreferrer" はリンクやフォーム送信にしか使えず、しかも「送らない」以外の選択肢がありません。対して referrerpolicy は画像・スクリプト・フレームにも書けて、「オリジンだけ送る」のような中間の指定ができます。

2つ目はリファラー以外の効果です。rel="noreferrer" は rel="noopener" を指定したときと同じ動作もするため、target="_blank" で開いた先のページから window.opener を通じて元のページを操作されることを防ぎます。セキュリティ上の目的で外部リンクに付けるなら、この働きも含めて rel="noreferrer" が適しています。

index.html
<!-- リファラーを送らず、window.opener からの操作も防ぐ -->
<a href="https://other.example/" target="_blank" rel="noreferrer">外部サイト</a>

<!-- リファラーはオリジンまで送りつつ、window.opener は無効にする -->
<a href="https://other.example/" target="_blank" rel="noopener" referrerpolicy="strict-origin">外部サイト</a>

両方を1つのリンクに書くと、noreferrer のほうが「リファラーを送らない」と決めてしまうため、referrerpolicy に別の値を書いても意図どおりには働きません。オリジンだけ送りたいのであれば、上の2つ目の例のように rel は noopener にとどめて、送信範囲は referrerpolicy で指定します。

リファラーが送られないとき

「アクセス解析に流入元が出ない」「サーバー側で Referer を見ているのに空になる」というときは、設定ミスとは限りません。ポリシー以外の理由でリファラーが付かない場面もあります。

HTTPS のページから HTTP のページへ移動している

既定値の strict-origin-when-cross-origin は、暗号化された通信から暗号化されていない通信へ下がるとき、リファラーを一切送りません。移動先がまだ HTTPS 化されていないサイトだと、送信側が何も設定していなくてもリファラーは届きません。strict が付く値と no-referrer-when-downgrade はすべてこの動きをします。受け取る側でどうしても必要なら、まず自サイトを HTTPS にするのが先です。

パス付きの URL を期待しているのにオリジンしか来ない

「リファラーは届いているが https://example.com/ としか入っていない」というのは、既定値が働いている状態です。別オリジンからの流入では、いまのブラウザーはオリジンまでしか送りません。相手のページのどこにリンクが置かれているかを知る手段としては、もうリファラーは使えないと考えてください。自サイト内の遷移であればフル URL が届くので、内部の導線分析には引き続き利用できます。

そもそもリファラーが発生しない遷移

アドレスバーに URL を直接入力した場合やブックマークから開いた場合は、きっかけになったページが存在しないので Referer は付きません。メールアプリやネイティブアプリ内のリンクから開かれたときも、送信元の情報が渡らないことがよくあります。解析ツールで「直接流入」に分類されるアクセスには、こうした遷移が混ざっています。

値の綴りが間違っている

無効な値を書いてもブラウザーはエラーを出さず、黙って既定値に戻ります。<meta name="referrer" content="noreferrer"> のようにハイフンを忘れているケース、referrerpolicy を referrerPolicy や referer-policy と書いてしまっているケースが典型です。意図した設定が効いているかどうかは、ブラウザーの開発者ツールのネットワークタブで実際のリクエストヘッダーを開き、Referer の値を見るのが確実です。

まとめ

referrerpolicy 属性は、<a>・<area>・<img>・<iframe>・<link>・<script> に書いて、その要素のリクエストで送るリファラーの範囲を決める属性です。値は「何も送らない」no-referrer から「常にフル URL を送る」unsafe-url まで8種類あり、origin が付けばオリジンだけ、strict が付けば HTTPS から HTTP へは送らない、と読み解けます。

ページ全体には <meta name="referrer">、サイト全体にはサーバーの Referrer-Policy ヘッダーが使え、個別の要素に書いた属性がそれらより優先されます。現在のブラウザーの既定値は strict-origin-when-cross-origin なので、外部にクエリー付き URL が渡る心配は基本的にありません。そのうえで、トークンを含む URL や社内システムのようにオリジンすら渡したくないページだけ、no-referrer や same-origin でさらに絞る——これが今どきの現実的な使い方です。

参考ページ