2011 年の旧記事は、古いプラグイン、ZIP の手動アップロード、アフィリエイトリンク、訪問者プロファイルを伴うクリック追跡を説明していました。これらをそのまま再現してはいけません。現在の安全な原則は、可能なら外部へ直接リンクし、サイト内の短いパスが必要な場合だけ、固定パスを固定 HTTPS 宛先へ対応させ、行き先と商業的関係の有無を読者に明示することです。
このガイドは 2026 年 9 月 1 日に更新したもので、トラフィック、顧客、収益を約束しません。出典確認のため、限定的に伏せ字化した歴史的原文を末尾に保存していますが、当時のサービス、ダウンロード、手順を推奨するものではありません。
Table of Contents
まず、リダイレクトが本当に必要かを確認する
外部への直接リンクは通常、最も単純で透明であり、プラグイン、キャッシュ、ログ、障害点を減らせます。「ここをクリック」ではなく「Example の製品ドキュメントを見る」のように行き先が分かるリンク文言を使います。明確な理由がなければ新しいウィンドウを強制せず、必要なら事前に伝え、rel="noopener" を使います。
サイト内リダイレクトが妥当なのは、将来移動する可能性がある長期リソースの固定アドレス、過去の短縮リンクの修復、または関係を明示した固定商用リンクなど、限定され説明可能な用途だけです。宛先の偽装、プラットフォーム規則の回避、リスクの隠蔽、訪問者が渡す任意宛先の受け入れに使ってはいけません。
3 つの実装方法
| 方法 | 適する場面 | 利点 | 主な責任 |
|---|---|---|---|
| 外部への直接リンク | 既定の選択 | 透明、リダイレクトチェーンなし、保守が最小 | 宛先と開示を定期確認 |
| 公式ディレクトリの保守中プラグイン | 多数のルートに UI、インポート、エクスポートが必要 | 非開発者にも管理しやすい | 更新、最小権限、ログの無効化・縮小 |
| Web サーバーの固定ルール | 安定した対応が少数で、サーバーを管理できる | WordPress 非依存で処理経路が短い | 設定レビュー、テスト、公開、ロールバック |
| 小さな WordPress 実装 | サイトコードとともに管理する少数の対応 | 挙動を監査でき、安全な WordPress リダイレクトを使える | コード、衝突、キャッシュの保守 |
プラグインを選ぶ場合は、WordPress 管理画面につながる公式プラグインディレクトリから、使用中の WordPress/PHP に対応し現在も保守される版をインストールします。Redirection はこの更新日時点でリリースが続く掲載例ですが、安全保証や商業的推奨ではありません。旧記事の第三者 ZIP、失効したダウンロード先、不明なミラーは使いません。
ステータスコードは「SEO スイッチ」ではない
| 状態 | 意味 | メソッドの扱い | この用途での指針 |
|---|---|---|---|
302 | 一時的 | 後続リクエストを GET に変える場合がある | 変更可能な固定・GET 専用マッピングの既定値 |
307 | 一時的 | メソッドと本文を保持 | 保持が必要な場合だけ。本文の端点は非 GET を拒否 |
301 | 恒久的 | クライアントが POST を GET に変える場合がある | 本当に長期不変で十分テストした宛先だけ |
308 | 恒久的 | メソッドと本文を保持 | 同じく本当に恒久的なルールだけ |
意味は HTTP Semantics(RFC 9110)に基づきます。ブラウザー、検索エンジン、CDN は恒久リダイレクトをキャッシュし、一時的なものもキャッシュ方針の影響を受けます。新規ルールは 302 で始め、検証後にだけ恒久化を判断します。変更時にはアプリケーションと CDN のキャッシュも削除します。
方法 A:プラグインを固定的かつ最小限に使う
ステージングでインストール・更新し、各短縮パスに完全一致の元パスと固定 HTTPS 宛先を設定します。正規表現、ワイルドカード、クエリーパラメーターから宛先を読む機能は有効にしません。?url=https://…、?next=…、javascript:、data: など非 HTTP(S) スキームを許すルートは作りません。不明な短縮パスは訪問者入力へ転送せず 404 のままにします。
既存ルールを先にエクスポート・バックアップします。/go/ がページ、投稿、カテゴリー、メディア、言語接頭辞、別プラグインと衝突しないか確認します。管理権限は必要な担当者だけに限定します。クリックログは既定で無効にし、最小化・削除要件を満たせないプラグインなら統計機能を使いません。公開後も復元可能な設定エクスポートとロールバック手順を残します。
方法 B:Web サーバーの固定ルールを 1 つ使う
次の Caddy 例はクエリー文字列のない GET /go/example-docs だけに一致し、宛先は定数です。path は既定で完全一致です。* を追加せず、{uri}、クエリー文字列、訪問者入力を宛先へ組み込みません。
@outbound_example {
method GET
path /go/example-docs
query ""
}
redir @outbound_example https://docs.example.org/product 302
既存の管理サービスの公開手順で読み込む前に、ステージング設定へ `caddy validate` を実行します。各フィールドは Caddy の `redir` とリクエストマッチャーの文書を参照してください。別のサーバーを使うサイトでは、その公式文書で同じ「完全一致パス → 固定宛先」を表現し、適用不能な設定をそのままコピーしません。
方法 C:最小限かつ固定の WordPress 実装
次のコードは、レビューとステージング後にサイト所有の小さなプラグインとして使えます。管理 UI はなく、GET だけを受け入れ、短縮パス上の全クエリー文字列を拒否し、コード内の対応表だけから宛先を得て、HTTPS と完全一致ホスト名を要求します。一時的にその外部ホストだけを許可し、`wp_safe_redirect()`を呼んだ後、フィルターを外して終了します。
<?php
/**
* Plugin Name: Fixed Outbound Redirects
*/
function lazying_fixed_outbound_routes() {
return array(
'go/example-docs' => array(
'url' => 'https://docs.example.org/product',
'host' => 'docs.example.org',
),
);
}
add_action(
'template_redirect',
static function () {
$method = isset( $_SERVER['REQUEST_METHOD'] )
? strtoupper( wp_unslash( $_SERVER['REQUEST_METHOD'] ) )
: '';
if ( 'GET' !== $method ) {
return;
}
$request_uri = isset( $_SERVER['REQUEST_URI'] )
? wp_unslash( $_SERVER['REQUEST_URI'] )
: '';
$path = wp_parse_url( $request_uri, PHP_URL_PATH );
if ( ! is_string( $path ) ) {
return;
}
$slug = trim( $path, '/' );
$routes = lazying_fixed_outbound_routes();
if ( ! isset( $routes[ $slug ] ) ) {
return;
}
$query = wp_parse_url( $request_uri, PHP_URL_QUERY );
if ( is_string( $query ) && '' !== $query ) {
nocache_headers();
status_header( 404 );
exit;
}
$route = $routes[ $slug ];
$destination = $route['url'];
$expected_host = strtolower( $route['host'] );
$scheme = strtolower( (string) wp_parse_url( $destination, PHP_URL_SCHEME ) );
$host = strtolower( (string) wp_parse_url( $destination, PHP_URL_HOST ) );
$user = wp_parse_url( $destination, PHP_URL_USER );
$pass = wp_parse_url( $destination, PHP_URL_PASS );
if (
'https' !== $scheme
|| $host !== $expected_host
|| null !== $user
|| null !== $pass
) {
status_header( 500 );
exit;
}
$allow_exact_host = static function ( $hosts ) use ( $host ) {
$hosts[] = $host;
return array_values( array_unique( $hosts ) );
};
add_filter( 'allowed_redirect_hosts', $allow_exact_host );
nocache_headers();
$sent = wp_safe_redirect( $destination, 302, 'Fixed Outbound Redirects' );
remove_filter( 'allowed_redirect_hosts', $allow_exact_host );
if ( $sent ) {
exit;
}
status_header( 500 );
exit;
},
0
);
`wp_safe_redirect()`は `wp_validate_redirect()`で許可ホストを検査しますが、実行を自動終了しないため、成功後にも exit が必要です。このコードは訪問者入力からホスト許可リストを広げず、ワイルドカードホストも使いません。対応表の変更はコードレビューを通します。将来管理画面を追加するなら、Settings APIを使い、manage_options など適切な権限を検査し、nonceを検証します。Nonce は認可の代わりではなく、公開された読み取り専用リダイレクト自体には nonce は不要です。
実際の宛先を示し、商業的関係をリンクの近くで開示する
短縮パスは隠れ蓑ではありません。リンク文言と近接する説明で、一般の読者が行き先を理解できるようにします。有料、スポンサー、アフィリエイトの関係はリンクの近くで分かりやすく開示し、フッターや規約ページだけに隠しません。米国向けには FTC Endorsement Guides の Q&Aを参照し、他地域では該当規則を確認します。
Google は現在、有料リンクに rel="sponsored" を推奨しています。nofollow も引き続き利用でき、組み合わせることもできます。どちらも、人が読める開示の代わりにはなりません。
<p><strong>Disclosure:</strong> I may receive a commission if you buy through this link.</p>
<p><a href="/go/example-docs" rel="sponsored nofollow">View Example's product documentation (paid link; opens Example)</a></p>
表示文言は各言語に翻訳し、事実に保ちます。クリック数、顧客数、転換率、収益を捏造してはいけません。リダイレクト回数は人、顧客、売上の件数ではありません。Google の外部リンク属性ガイドに現在の sponsored/nofollow の使い方があります。
クリックログ:既定では収集しない
最小実装はクリックを記録しません。ただしサーバーアクセスログにはパス、IP アドレス、User-Agent、参照元、クエリー文字列が残る場合があります。「プラグインの追跡を無効化したからログがない」と仮定せず、実際の基盤を確認します。明確で必要な目的がなければ、そのルートの詳細ログを抑止するか、できるだけ早く不可逆に集計します。完全な IP、User-Agent、参照元 URL、訪問者識別子は既定で保存しません。
計測が必要なら、目的に必要な最小フィールドだけ、たとえば短期間の「日付 + ルート + 集計数」を残します。ボットや重複リクエストで数字は歪みます。目的、法的根拠、保存期間、受領者、アクセス/削除方法を示し、適用法に従って同意・拒否手段を評価します。Cookie、端末ストレージ、リンク装飾には ICO のストレージおよびアクセス技術ガイドを参照できます。個人データを扱う WordPress プラグインは、同プラットフォームのプライバシー通知、エクスポーター、消去機能も実装すべきです。
ステージングでのテストと受け入れ条件
先にデータベース、プラグイン設定、サーバー設定をバックアップし、1 ルートだけ変更します。例のホストをステージングドメインに置き換えて実行します。
curl --silent --show-error --dump-header - --output /dev/null
https://staging.example.org/go/example-docs
curl --silent --show-error --dump-header - --output /dev/null
--request POST https://staging.example.org/go/example-docs
curl --silent --show-error --dump-header - --output /dev/null
'https://staging.example.org/go/example-docs?url=https://evil.example'
curl --silent --show-error --location --max-redirs 5 --output /dev/null
--write-out '%{http_code} %{url_effective}n'
https://staging.example.org/go/example-docs
受け入れ条件は、クエリーなしの完全一致 GET が期待する HTTPS 宛先へ 1 回だけ転送されること、POST と url クエリーが転送されないこと、不明 slug が 404 になること、最終ページが期待どおりであること、ループがないこと、訪問者のクエリーが伝播しないことです。ログイン中/外、モバイル、キャッシュ有効/無効、CDN エッジを別々にテストします。コードがステージングに未導入なら、このコマンドは現サイトの挙動だけを試し、サンプル実装を証明しません。
多言語サイトでは /go/example-docs を各言語で共有するか決めます。/en/、/ja/ などの接頭辞があるなら、言語パスを飲み込むワイルドカードではなく、完全一致対応を個別に列挙します。パーマリンクや宛先の変更後は、WordPress リライトルール、プラグイン優先順位、ページ slug、リバースプロキシ、CDN の衝突とリダイレクトチェーンを調べます。
ロールバックと停止条件
公開前にルールのエクスポート、コード版、旧設定を保存し、302 で限定的に始めます。誤った宛先、ループ、消えないキャッシュ、不明パスの捕捉、リクエストパラメーターの転送、開示範囲外のログ、宛先ドメインの移転、セキュリティ警告があれば、直ちにそのルールを無効化し、キャッシュを削除して直接リンクへ戻します。統計を守るためにロールバックを遅らせません。
公開前の最小チェックリスト:
- 直接リンクで十分ではないか。
- 元は予約済みの完全一致 slug、宛先は固定 HTTPS URL と完全一致ホストか。
- 非
GET、クエリー指定の宛先、非 HTTP(S) スキーム、不明 slug を拒否するか。 - slug/言語接頭辞、キャッシュ/CDN、ループ、宛先所有者を確認したか。
- 商業的関係をリンク近くで明示し、リンク文言を理解できるか。
- IP/User-Agent ログは既定で無効で、分析は最小化され削除期限があるか。
- バックアップ、設定エクスポート、レビュー担当、テスト証拠、1 手順のロールバックがあるか。
参考資料
- WordPress Developer Resources:`wp_safe_redirect()`、`wp_validate_redirect()`、`template_redirect`
- WordPress Plugin Handbook:Security、Settings API、Roles and Capabilities、Nonces、Privacy
- OWASP Unvalidated Redirects and Forwards Cheat Sheet
- HTTP Semantics(RFC 9110)
- Google Search Central:Qualify your outbound links
- FTC's Endorsement Guides: What People Are Asking
- ICO:Guidance on the use of storage and access technologies
- Caddy:redir、Request matchers
歴史的原文アーカイブ(出典確認専用・実行禁止)
以下は 2011 年の source export にある可視本文全体で、限定的な伏せ字以外は改変していません。古い追跡情報や個人・アカウント状の識別子を再公開しないため、Taskcity 紹介パラメーター値(2 箇所)、旧自サイト追跡パス(3 箇所)、Filemarkets のアカウント状ダウンロードパス(1 箇所)を角括弧のプレースホルダーに置換しました。元文字列は source_export と Git の出典履歴だけに残ります。旧プラグインのダウンロード、推奨、訪問者プロファイリング、商業的主張は否定された歴史資料として保存しています。リンクは失効、移転、危険化している可能性があるため、アクセスも実行もしないでください。
WordPress 怎样实现“站外链接”的跳转?
——WordPress短链接插件Pretty Link
**比如说我在一篇文章里添加了一个超链接,我想让这个超链接显示成本站的链接,(鼠标放上去变成小手,浏览器左下角显示的是本站的一个链接)但是点击后跳转成外链,这样如何实现?**
在[http://earnfs.sinaapp.com](http://earnfs.sinaapp.com/[historical redirect path redacted])站点中:
[http://www.taskcity.com/?dn=[historical referral value redacted]](http://www.taskcity.com/?dn=[historical referral value redacted])=>[http://earnfs.sinaapp.com/[historical redirect path redacted]](http://earnfs.sinaapp.com/[historical redirect path redacted])
**可以使用缩短连接插件**
**Pretty Link (推荐)**
**或**
**WordPress ShortUrl Plugin**
Petty Link可以生成基于你的域名的短网址,类似tinyurl.com, bit.ly等短网址服务的链接,并且这个链接基于你自己的域名,你可以对这些生成的网址链接进行点击跟踪,监测点户的来源地、浏览器、操作系统等,非常适合用来做推荐联盟链接等。
这款插件可以自定义URL,不过,前提是不能和已经存在的或者已经在使用的%postname%相同,使用Petty Link插件后,它会让你的网站变得更加的简洁、
**Petty Link插件安装使用:**
1. [下载Petty Link插件](http://filemarkets.com/file/[historical account/download path redacted]),解压后,把文件夹上传到wp-content/plugins/目录下,登录WordPress管理后台,点击“Plugins”找到上传的插件,激活该插件。
2. 激活该插件后,在后台页面的右侧最下方,会出现Pretty Link的图标,然后,在里面进行相关的设置。
**Pretty Link有以下选项:**
**Pretty Link:**页面中主要是当前添加的链接、点击量、组等相关信息
**Add New Link:**添加链接

**Groups:**创建组,让这些组使用这些pretty links
**Hits:**图示最近一段时间的点击量、流量IP、转向的链接,方便你的统计使用。
**Tools:**获取Pretty Link链接到工具栏安装书签,当你浏览网页,只要单击书签就可以创建Pretty Link
**Options:**设置相关信息
- **Link Option Defaults**:设置是否添加跟踪链接、nofollow及相关属性
- **PrettyBar Options**:设置Pretty Bar的是否显示标题、说明、分享链接及URL。
- **Reporting Options**:报告选项,不包含那些IP地址,在统计的时候对其进行排除。
**Pretty Link Pro**:设置PRO账户信息
这款插件的功能还是比较强的,这里这是简单的做了点介绍,更多更深的东西,还是需要大伙自己体会。
