NL新增的外链跳转提示页面源码

相信大家在NL点击外链的时候已经发现,NL现在会有一个外链提示页面了。

Image description![Image description](https://s.rmimg.com/2025-01-03/1735879741-316304-image.png)

实际效果点以下地址

https://www.163.com

这样做的好处一是网站权重不会流失,二是能够看用户更清楚的看到下一个页面的链接地址是什么,避免被钓鱼。

页面源码如下,其实就是截断 `/goto/` 后面的URL内容来提示用户。

``` <?php // 获取跳转目标 URL $redirectUrl = $_SERVER['REQUEST_URI']; $redirectUrl = str_replace('/goto/', '', $redirectUrl);

// 初始化错误消息和解码后的链接变量
$errorMessage = null;
$decodedLink = null;

// 检查 URL 是否为空
if (empty($redirectUrl)) {
$errorMessage = “跳转链接无效或为空。请检查您的链接。”;
$redirectUrl = “#”; // 默认值
} else {
// 对链接进行解码
$decodedLink = urldecode($redirectUrl);

// 验证解码后的链接是否为有效的 URL
if (filter_var($decodedLink, FILTER_VALIDATE_URL)) {
    // 确保链接是外部链接
    $host = parse_url($decodedLink, PHP_URL_HOST);
    if ($host === $_SERVER['HTTP_HOST']) {
        $errorMessage = "不支持站内链接跳转。";
        $redirectUrl = "#"; // 不合法时默认值
    } else {
        $redirectUrl = $decodedLink; // 合法的外部链接
    }
} else {
    $errorMessage = "无效的 URL,请检查链接格式。";
    $redirectUrl = "#"; // 无效链接时默认值
}

}

// 对最终链接进行 HTML 特殊字符编码,确保安全
$redirectUrl = htmlspecialchars($redirectUrl, ENT_QUOTES, ‘UTF-8’);
?>

<!DOCTYPE html>
<html lang=“zh-CN”>
<head>
<meta charset=“UTF-8”>
<meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
<title>跳转提示</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #009966;
background-image: linear-gradient(135deg, #009966, #006644);
color: #ffffff;
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container {
text-align: center;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 10px;
padding: 20px;
width: 90%;
max-width: 480px;
box-sizing: border-box;
}
.container h1 {
font-size: 22px;
margin-bottom: 10px;
}
.container p {
font-size: 14px;
margin-bottom: 20px;
word-wrap: break-word;
word-break: break-all;
}
.container a {
display: inline-block;
background-color: #FF9933;
color: #ffffff;
text-decoration: none;
font-size: 14px;
font-weight: bold;
padding: 10px 20px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.container a:hover {
background-color: #cc7a29;
}
.container .small-text {
font-size: 12px;
margin-top: 15px;
color: rgba(255, 255, 255, 0.8);
}
.error-message {
color: #FF0000;
font-size: 16px;
font-weight: bold;
margin-bottom: 20px;
}
/* 支持老旧浏览器的渐变背景 */
@supports not (background: linear-gradient(135deg, #009966, #006644)) {
body {
background-color: #009966;
}
}
</style>
</head>
<body>
<div class=“container”>
<h1>跳转提示</h1>

    &lt;?php if (isset($errorMessage)): ?&gt;
        &lt;div class="error-message"&gt;&lt;?= $errorMessage ?&gt;&lt;/div&gt;
    &lt;?php else: ?&gt;
        &lt;p&gt;您正在离开本站并访问以下链接:&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;&lt;?= $redirectUrl ?&gt;&lt;/strong&gt;&lt;/p&gt;
        &lt;a href="&lt;?= $redirectUrl ?&gt;" rel="noopener noreferrer"&gt;继续访问&lt;/a&gt;
    &lt;?php endif; ?&gt;

    &lt;p class="small-text"&gt;如果您不想访问此链接,请关闭此页面。&lt;/p&gt;
&lt;/div&gt;

</body>
</html>
```

这个放到哪里呢 ?

@“alay”#p202080 public下建一个叫 </s>goto<e>的文件夹,放进去。

Image description</s>Image description<e>


@“alay”#p202080 你点击外链就显示了

@“James”#p202086 我试试!

@“James”#p202086 放进去了,就一个index.php,其他哪里还要修改吗?貌似没效哦。

https://sx.sd/d/305

@“alay”#p202098 这只是跳转页面,还需要把所有的站外链接替换成跳转页面的URL,因此还需要用拓展或者改文件

@“Yucho”#p202100 如何替换呢?

@“alay”#p202101 @yucho 说得对,这是跳转页面的代码,你要把站外链接替换,我是写在nl专门的一个patch里边的,没有单独的插件。

@“alay”#p202101 前端或者后端替换。不怎么了解flarum

@“alay”#p202101 插件源码


```
class FormatContent
{
public function __invoke($serializer, $model, $attributes)
{
if (isset($attributes[“contentHtml”])) {
$newHTML = $attributes[“contentHtml”];

        // 检查 HTML 内容是否为空
        if (!is_null($newHTML)) {
            // 使用正则表达式匹配所有的链接
            $newHTML = preg_replace_callback(
                '/&lt;a\s+(?:[^&gt;]*?\s+)?href=["\']([^"\']+)["\']([^&gt;]*)&gt;(.*?)&lt;\/a&gt;/is',
                function ($matches) {
                    $url = $matches[1]; // 获取链接的 href 值
                    $attributes = $matches[2]; // 获取链接的其他属性
                    $text = $matches[3]; // 获取链接的文本

                    // 判断是否为站内链接或内部链接
                    if ($this-&gt;isExternalLink($url)) {
                        // 对非站内链接添加跳转提示
                        $redirectUrl = '/goto/' . urlencode($url);
                        return "&lt;a href=\"{$redirectUrl}\" {$attributes} target=\"_blank\" rel=\"noopener noreferrer\"&gt;{$text}&lt;/a&gt;";
                    }

                    // 保持原样处理站内链接
                    return $matches[0];
                },
                $newHTML
            );
        }

        $attributes['contentHtml'] = $newHTML;
    }

    return $attributes;
}

/**
 * 检查是否为外部链接
 *
 * @param string $url
 * @return bool
 */
private function isExternalLink($url)
{
    // 获取当前请求的主机名
    $currentHost = isset($_SERVER['HTTP_HOST']) ? rtrim($_SERVER['HTTP_HOST'], '/') : '';

    // 获取目标 URL 的主机名
    $urlHost = parse_url($url, PHP_URL_HOST);

    // 如果目标 URL 没有主机名,或者是相对路径,认为是内部链接
    if (!$urlHost) {
        return false;
    }

    // 标准化主机名
    $currentHost = strtolower($currentHost);
    $urlHost = strtolower($urlHost);

    // 检查是否为同一主机
    return $currentHost !== $urlHost;
}

}
```

`extend.php` 里边Inject一下

``` (new Extend\ApiSerializer(PostSerializer::class)) ->attributes(FormatContent::class), (new Extend\ApiSerializer(BasicPostSerializer::class)) ->attributes(FormatContent::class), ```

这是一个好东西,,,双休时候搞搞

常见的站点,能不能有个白名单,可以直接访问

@“x”#p202110 嗯,目前github是直接过的。 其它的考虑在后台加个白名单 。

建议设置多一点白名单 尤其是大厂网页。或者增加个允许关闭的功能

@“培根冲冲冲”#p202206 你是不是想要个等级权限到了能关闭这个跳转的按钮?

@“金子会发光”#p202227 差不多哈哈哈

感谢大佬无私分享!

NL不登录不是不显示外链吗,

@“zeruns”#p202244 之前的对游客不太友好,所以现在用户不登录也可以显示链接啦。