WordPress二级域名独立跳转页

Ginc
Ginc
Ginc
管理员
78
文章
0
粉丝
建站开发评论434阅读模式
前言

在博客中,我们通常会用go跳转来对文章中出现的外链来进行内页跳转。但是在看‘广然笔记’的时候,发现他用的是独立二级域名进行跳转,询问后得知这是类似CSDN的跳转模式。这种跳转方式跟主站完全分离,进一步提升安全性跟SEO友好。

一、先来直观的感受下go跳转跟独立域名跳转

1、普通跳转以腾讯云随便一篇文章为例

这是文章地址文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

这是跳转页面,跳转地址会出现服务器跳转页目录文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

2、独立跳转就以CSDN为例,也是随便一篇文章文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

这是文章地址文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

这是独立跳转页面,跳转地址为独立二级域名,不再出现服务器目录文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

二、实现方法

1、整体架构

文章源自今夕何夕兮-https://www.ginc.site/building-and-development1408.html

用户点击外部链接

WordPress 过滤器改写为 https://go.example.com/?a=base64编码

go.example.com 独立站点(与 WordPress 无关)

安全提示页 → 用户确认 → 跳转到目标地址

2、DNS解析

类型     主机记录     记录值
A          go             你的服务器IP

3、建站

1、使用宝塔建立go.example.com网站,并将根目录设置为go.example.com

这里没截图。

2、手动创建

certbot certonly --webroot -w /www/wwwroot/go.example.com -d go.example.com
mkdir -p /www/wwwroot/go.example.com
目录结构
/www/wwwroot/go.example.com/
├── index.php
├── style.css
└── favicon.ico

4、Nginx配置

server {
    listen 80;
    server_name go.example.com;

    root /www/wwwroot/go.example.com;
    index index.php index.html;

    # 限制 /go/ 目录被搜索引擎收录
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_pass  unix:/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }

    # 禁止访问隐藏文件和非必要文件
    location ~ /\.(?!well-known) {
        deny all;
    }

    # 防盗链 - 只允许本站和主站引用
    valid_referers none blocked *.example.com;
    if ($invalid_referer) {
        return 403;
    }

    # SSL(申请证书后取消注释)
    # listen 443 ssl;
    # ssl_certificate     /etc/letsencrypt/live/go.example.com/fullchain.pem;
    # ssl_certificate_key /etc/letsencrypt/live/go.example.com/privkey.pem;
}

上面的配置信息是二级域名go.example.com网站的nginx配置。

5、index文件

这里我把我的index源码发出来,各位可以按需修改。

<?php
/**
 * 外部链接安全跳转中转页
 * 独立二级域名站点,与 WordPress 无关
 * 用法: https://go.ginc.site/?a=base64_encode(目标URL)
 */

// ============ 基本配置 ============
$default_url  = 'https://www.ginc.site/';  // 默认跳转地址
$site_name    = '今夕何夕兮';               // 站点名称
$logo_url     = 'https://go.example.com/wp/logo/.png'; // Logo
$countdown    = 10;                         // 自动跳转秒数

// ============ 参数校验 ============
$link         = '';
$show_warning = false;

if (isset($_GET['a']) && !empty($_GET['a'])) {
    $decoded = base64_decode($_GET['a'], true);

    // strict 解码成功 + 合法 URL
    if ($decoded !== false && filter_var($decoded, FILTER_VALIDATE_URL)) {
        $scheme = parse_url($decoded, PHP_URL_SCHEME);

        if (in_array($scheme, ['http', 'https'], true)) {
            $link = $decoded;
            $show_warning = true;
        }
    }
}

// 无有效参数时重定向到主站
if (empty($link)) {
    header('Location: ' . $default_url, true, 302);
    exit;
}

// ============ 输出安全处理 ============
$text_link  = htmlspecialchars($link, ENT_QUOTES, 'UTF-8');
$href_link  = filter_var($link, FILTER_SANITIZE_URL);
$display    = parse_url($link, PHP_URL_HOST) ?: $text_link;
$json_link  = json_encode($link, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP);
?>
<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="robots" content="noindex, nofollow, noarchive, nosnippet">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="referrer" content="no-referrer">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <link rel="icon" href="<?php echo $logo_url; ?>" type="image/png">
    <title>安全提示 - <?php echo $site_name; ?></title>
</head>
<body>

<div class="page">
    <div class="deco-bar"></div>

    <div class="card">
        <!-- Logo -->
        <div class="card-header">
            <a href="<?php echo $default_url; ?>" class="logo-link" rel="noopener">
                <img src="<?php echo $logo_url; ?>" alt="<?php echo $site_name; ?>" class="logo">
            </a>
        </div>

        <!-- 图标 -->
        <div class="status-icon">
            <svg width="40" height="40" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" stroke-width="1.5"
                 stroke-linecap="round" stroke-linejoin="round">
                <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
                <polyline points="15 3 21 3 21 9"/>
                <line x1="10" y1="14" x2="21" y2="3"/>
            </svg>
        </div>

        <!-- 标题 -->
        <h1 class="title">您即将离开本站</h1>

        <!-- 目标地址 -->
        <div class="url-box">
            <div class="url-label">目标地址</div>
            <div class="url-host"><?php echo htmlspecialchars($display, ENT_QUOTES, 'UTF-8'); ?></div>
            <div class="url-full" title="<?php echo $text_link; ?>"><?php echo $text_link; ?></div>
        </div>

        <!-- 安全提示 -->
        <div class="warning-box">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" stroke-width="2"
                 stroke-linecap="round" stroke-linejoin="round">
                <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
                <line x1="12" y1="9" x2="12" y2="13"/>
                <line x1="12" y1="17" x2="12.01" y2="17"/>
            </svg>
            <span>该链接非本站所有,跳转后请注意您的账号和财产安全,谨防钓鱼诈骗</span>
        </div>

        <!-- 按钮 -->
        <div class="btn-group">
            <button class="btn btn-ghost" onclick="goBack()">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
                     stroke="currentColor" stroke-width="2"
                     stroke-linecap="round" stroke-linejoin="round">
                    <line x1="19" y1="12" x2="5" y2="12"/>
                    <polyline points="12 19 5 12 12 5"/>
                </svg>
                返回上一页
            </button>
            <a href="<?php echo $href_link; ?>" id="goBtn"
               class="btn btn-primary" target="_blank" rel="nofollow noopener noreferrer">
                继续访问
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
                     stroke="currentColor" stroke-width="2"
                     stroke-linecap="round" stroke-linejoin="round">
                    <line x1="5" y1="12" x2="19" y2="12"/>
                    <polyline points="12 5 19 12 12 19"/>
                </svg>
            </a>
        </div>

        <!-- 倒计时 -->
        <div class="countdown" id="countdown">
            <div class="countdown-bar">
                <div class="countdown-bar-inner" id="bar"></div>
            </div>
            <span id="timer"><?php echo (int)$countdown; ?></span> 秒后自动跳转
            <button class="cancel-btn" onclick="cancelAutoJump()">暂停</button>
        </div>

        <!-- 底部 -->
        <div class="footer">
            <span>由</span>
            <a href="<?php echo $default_url; ?>" rel="noopener"><?php echo $site_name; ?></a>
            <span>提供安全跳转服务</span>
        </div>
    </div>
</div>

<script>
    // 返回上一页
    function goBack() {
        if (window.history.length > 1) {
            history.back();
        } else {
            window.location.href = <?php echo json_encode($default_url); ?>;
        }
    }

    // 自动跳转
    var total    = <?php echo (int)$countdown; ?>;
    var seconds  = total;
    var timer    = document.getElementById('timer');
    var bar      = document.getElementById('bar');
    var paused   = false;
    var target   = <?php echo $json_link; ?>;

    // 进度条
    bar.style.transition = 'width 1s linear';
    bar.style.width = '100%';

    var tick = setInterval(function() {
        if (paused) return;

        seconds--;
        timer.textContent = seconds;
        bar.style.width = (seconds / total * 100) + '%';

        if (seconds <= 0) {
            clearInterval(tick);
            window.open(target, '_blank', 'noopener');
        }
    }, 1000);

    function cancelAutoJump() {
        paused = !paused;
        var btn = document.querySelector('.cancel-btn');
        btn.textContent = paused ? '继续' : '暂停';
    }
</script>

</body>
</html>

6、样式修改

这里也是源码,请按需修改。

/* ========== 样式 ========== */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --bg: #f7f8fa;
    --card: #ffffff;
    --text: #1d2129;
    --text-2: #4e5969;
    --text-3: #86909c;
    --accent: #165dff;
    --accent-hover: #0e42d2;
    --accent-light: #e8f0fe;
    --warn-bg: #fff7e8;
    --warn-border: #ffcf69;
    --warn-text: #b25000;
    --border: #e5e6eb;
    --radius: 14px;
    --font: 'Noto Sans SC', -apple-system, 'PingFang SC', 'Helvetica Neue', sans-serif;
    --mono: 'JetBrains Mono', 'Menlo', 'Consolas', monospace;
}

body {
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ========== 顶部装饰条 ========== */
.deco-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, #165dff, #722ed1, #eb2f96, #fa8c16);
    background-size: 300% 100%;
    animation: barShift 8s ease infinite;
    z-index: 100;
}

@keyframes barShift {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 100% 50%; }
}

/* ========== 布局 ========== */
.page {
    width: 100%;
    max-width: 500px;
    padding: 24px 16px;
}

/* ========== 卡片 ========== */
.card {
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04),
                0 8px 32px rgba(0, 0, 0, 0.06);
    border: 1px solid var(--border);
    padding: 40px 32px 28px;
    text-align: center;
    animation: enter 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes enter {
    from { opacity: 0; transform: translateY(16px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ========== Logo ========== */
.card-header { margin-bottom: 20px; }

.logo-link { display: inline-block; text-decoration: none; }

.logo {
    height: 32px;
    width: auto;
    opacity: 0.8;
    transition: opacity 0.2s;
}

.logo:hover { opacity: 1; }

/* ========== 图标 ========== */
.status-icon {
    width: 68px;
    height: 68px;
    margin: 0 auto 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    background: var(--accent-light);
    animation: pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s both;
}

@keyframes pop {
    from { opacity: 0; transform: scale(0.4); }
    to   { opacity: 1; transform: scale(1); }
}

/* ========== 标题 ========== */
.title {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 20px;
    animation: up 0.4s ease 0.2s both;
}

/* ========== 地址框 ========== */
.url-box {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 16px;
    text-align: left;
    animation: up 0.4s ease 0.25s both;
}

.url-label {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 4px;
}

.url-host {
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 4px;
}

.url-full {
    font-size: 12px;
    font-family: var(--mono);
    color: var(--accent);
    word-break: break-all;
    line-height: 1.6;
    opacity: 0.8;
}

/* ========== 警告 ========== */
.warning-box {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    background: var(--warn-bg);
    border: 1px solid var(--warn-border);
    border-radius: 10px;
    padding: 12px 16px;
    margin-bottom: 24px;
    text-align: left;
    color: var(--warn-text);
    font-size: 13px;
    line-height: 1.7;
    animation: up 0.4s ease 0.3s both;
}

.warning-box svg {
    flex-shrink: 0;
    margin-top: 2px;
}

/* ========== 按钮 ========== */
.btn-group {
    display: flex;
    gap: 12px;
    margin-bottom: 20px;
    animation: up 0.4s ease 0.35s both;
}

.btn {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 12px 16px;
    font-size: 14px;
    font-weight: 500;
    font-family: var(--font);
    border-radius: 10px;
    border: none;
    cursor: pointer;
    text-decoration: none;
    transition: all 0.2s ease;
    line-height: 1.5;
}

.btn-ghost {
    background: transparent;
    color: var(--text-2);
    border: 1px solid var(--border);
}

.btn-ghost:hover {
    background: var(--bg);
    border-color: #d0d3d8;
}

.btn-primary {
    background: var(--accent);
    color: #fff;
}

.btn-primary:hover {
    background: var(--accent-hover);
    transform: translateY(-1px);
    box-shadow: 0 4px 16px rgba(22, 93, 255, 0.3);
}

.btn:active {
    transform: scale(0.97);
}

/* ========== 倒计时 ========== */
.countdown {
    font-size: 12px;
    color: var(--text-3);
    margin-bottom: 20px;
    animation: up 0.4s ease 0.4s both;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.countdown-bar {
    width: 80px;
    height: 3px;
    background: var(--border);
    border-radius: 2px;
    overflow: hidden;
}

.countdown-bar-inner {
    height: 100%;
    background: var(--accent);
    border-radius: 2px;
    width: 100%;
}

#timer {
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    min-width: 16px;
    text-align: right;
}

.cancel-btn {
    background: none;
    border: none;
    color: var(--text-2);
    font-size: 12px;
    font-family: var(--font);
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 4px;
    transition: all 0.15s;
}

.cancel-btn:hover {
    background: var(--bg);
    color: var(--text);
}

/* ========== 底部 ========== */
.footer {
    padding-top: 16px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--text-3);
    animation: up 0.4s ease 0.45s both;
}

.footer a {
    color: var(--text-2);
    text-decoration: none;
    font-weight: 500;
}

.footer a:hover { color: var(--accent); }

/* ========== 通用动画 ========== */
@keyframes up {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ========== 移动端 ========== */
@media (max-width: 540px) {
    .card { padding: 32px 20px 24px; }

    .btn-group { flex-direction: column-reverse; }

    .title { font-size: 16px; }

    .url-host { font-size: 14px; }
}

7、主站 `functions.php` 过滤

依旧源码,按需修改。

// ========== 外部链接改写为二级域名中转页 ==========
add_filter('the_content', 'external_link_redirect', 999);

function external_link_redirect($content)
{
    $home_url  = home_url();                  // https://www.ginc.site
    $redirect  = 'https://go.example.com';      // 中转域名

    $content = preg_replace_callback(
        '/<a\s([^>]*?)href="(https?:\/\/[^"]+)"([^>]*)>/i',
        function ($m) use ($home_url, $redirect) {
            $url = $m[2];

            // 跳过站内链接
            if (strpos($url, $home_url) === 0) return $m[0];

            // 跳过中转站自身
            if (strpos($url, $redirect) === 0) return $m[0];

            // 跳过图片/媒体/文档
            if (preg_match('/\.(jpg|jpeg|png|gif|ico|webp|svg|bmp|tiff|mp3|mp4|pdf|zip|rar)(\?.*)?$/i', $url)) {
                return $m[0];
            }

            $encoded = base64_encode($url);

            return sprintf(
                '<a %shref="%s/?a=%s"%s rel="nofollow noopener" target="_blank">',
                $m[1], $redirect, $encoded, $m[3]
            );
        },
        $content
    );

    return $content;
}

// 评论区也生效
add_filter('comment_text', 'external_link_redirect', 999);

三、测试验证

当然这一步可以省略,因为有错误跳转页面会404

1. 确认 DNS 解析生效:自行搜索ping工具 ping go.example.com

2. 浏览器访问 https://go.example.com/?a=aHR0cHM6Ly9leGFtcGxlLmNvbQ==

3. 测试无参数访问 → 应自动跳回主站   https://www.example.com/

4. 测试恶意参数 → 应自动跳回主站 https://www.example.com/?a=javascript:alert(1)

这里放个链接:www.baidu.com,可以点击进去看一下,样式、内容可自行修改

特别鸣谢: 广然笔记

 

转载请注明来自:今夕何夕兮
除特别声明外,本站内容遵循 CC-BY-NC-SA4.0 协议授权。部分资源收集于网络,只做学习和交流使用,版权归原作者所有。

weinxin
提示:
若文章中图片、链接等信息出错,请及时反馈,博主将在第一时间更新。谢谢大家!
 
Ginc
  • 本文由 Ginc 发表于2026年8月1日
  • 转载请保留本文链接:WordPress二级域名独立跳转页:https://www.ginc.site/building-and-development1408.html
匿名

发表评论

匿名网友
确定

拖动滑块以完成验证