前天在老麦博客中看到" 给Twikoo添加链接跳转中间页“博文,因为外部链接你无法确定未来某一天可能就会变成不安全链接,从而影响到自己博客。同时又见到 大大的小蜗牛也是因为安全的原因,把博客评论换成了GitHub Discussions。网上也有不少的案例,因为某个链接的原因,而被请喝茶或电话让自己排查。今天在 不亦乐乎那见链接也是跳转到中间页,于是请教了下怎么实现的,感谢。之后经过与 AI 的博弈,搞定。这次使用 ChatGPT 跟 Claude 都不行,说了一堆,完全不懂,最后使用 coze 搞定基本框架,然后再来回沟通逐步完善功能。估计跟它使用的 ChatGPT 4.0 接口有关。想充值 ChatGPT,奈何月费太贵了。
新建 js 文件,如:tiaozhuan.js。里面的网址为排除跳转中间页。
function checkParent(element, classNames) {
while (element) {
if (element.classList && classNames.some(cn => element.classList.contains(cn))) {
return true;
}
element = element.parentElement;
}
return false;
}
var excludedClasses = ['talks_comments','tiaozhuan-button']; // 添加需要排除的a标签类名class
window.addEventListener('load', (event) => {
document.body.addEventListener('click', function(e) {
let target = e.target;
while (target && target.nodeName !== 'A') {
target = target.parentNode;
}
if (target && target.nodeName === 'A' &&
!checkParent(target, excludedClasses) &&
!target.href.includes('koobai.com') &&
!target.href.includes('douban.com') &&
!target.href.includes('bilibili.com') &&
!target.href.includes('github.com') &&
target.hostname !== window.location.hostname) {
e.preventDefault();
let encodedUrl = btoa(target.href); // Base64 encode the URL
let url = '/tiaozhuan?target=' + encodedUrl;
window.open(url, '_blank');
}
});
});
在模板_default目录下,新建一个 html,如tiaozhuan.html。
{{ define "body_classes" }}page-tiaozhuan{{ end }}
{{ define "main" }}
<div class="tiaozhuan-all">
<div class="tiaozhuan-nrong">
<div class="tiaozhuan-title">即将离开 {{ .Site.Title }},跳转到以下外部链接</div>
<div id="tiaozhuan-link"></div>
<div class="tiaozhuan-info">请自行识别该链接是否安全,并保管好个人信息。</div>
<div class="tiaozhuan-button"><a href='' id='direct-link'>继续访问</a></div>
</div>
</div>
<script>
const params = new URLSearchParams(window.location.search);
const encodedTarget = params.get('target');
const target = atob(encodedTarget); // 使用 atob 进行 Base64 解码
if (target) {
document.getElementById('direct-link').href = target;
document.getElementById('tiaozhuan-link').textContent = '' + target; // 直接显示目标地址
} else {
console.error('未指定重定向目标。');
}
</script>
{{ end }}
相关 css,根据主题风格调整。其中 background 为明暗模式下不同的背景图。
.tiaozhuan-all{
position: relative;
box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px;
border-radius: 10px;
background: #fff url(/tiaozhuanico.webp) no-repeat center center / cover;
color: #666;
word-break: break-all;
max-width: 700px;
height: 350px;
text-align: center;
font-size: 0.85rem;
overflow: hidden;
margin: 100px auto 0;
@include breakpoint('small') {
aspect-ratio: 2 / 1;
height: auto;
}
}
.tiaozhuan-nrong{
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 20px 20px 30px 20px;
}
.tiaozhuan-title{
font-size: 1.3rem;
font-family: var(--font-family-title);
color: #222;
line-height: 1.4;
margin-bottom: 4px;
}
.tiaozhuan-info{
margin-top: 6px;
}
.tiaozhuan-button{
margin-top: 20px;
}
.tiaozhuan-button a{
color: var(--text-highlight-color);
border-radius: 4px;
padding: 10px 30px;
font-family: var(--font-family-title);
font-size: 0.85rem;
border: 0.5px solid var(--text-highlight-color);
display: inline-block;
}
@media (prefers-color-scheme: dark) {
.tiaozhuan-all{
background: var(--background-dark-color) url(/tiaozhuandark.webp) no-repeat center center / cover;
color: #acacac;
}
.tiaozhuan-title{
color: #ddd;
}
}
最后在页尾引用js文件即可,如
<script src="/js/tiaozhuan.js"></script>
搞定,整体思路是:js文件识别链接的a标签,并把链接用 base64 编码,同时排除一些不需要跳转中间页的class或网站。然后跳转到tiaozhuan.html文件中(链接格式为/tiaozhuan?target=base64编码),html文件承担了中间页具体信息,及跳转动作。如使用base64解码跳转的链接。
以上为全局引用JS方法,判断 a 标签。下面利用 Hugo 内置的 render-link.html 实现。在模板_default/_makup目录下新建 render-link.html文件。思路是直接给链接添加 “/tiaozhuan?target=base64编码”。下面代码中的 “/” 为排除内链;网址为排除特定地址。感谢 大大的小蜗牛提示的 render-link 方法。
{{ $url := .Destination }}
<a
{{ if or (in $url "koobai.com") (strings.HasPrefix $url "/") }}
href="{{ $url }}"
{{ else }}
href="/tiaozhuan?target={{ $url | base64Encode }}"
{{ end }}
{{ if strings.HasPrefix .Destination "http" }} target="_blank"{{ end }}
>
{{ .Text | safeHTML }}</a>
针对无法给链接添加 “/tiaozhuan?target=base64编码” 的,譬如 Artalk 评论,可以特定使用 js 判断。里面的.atk-comment-wrap a 就是 Artalk 评论的 a 标签;网址为排除特定地址。
document.body.addEventListener('click', function(e) {
let target = e.target.closest('.atk-comment-wrap a, .datacont a');
if (target && !target.href.includes('koobai.com')) {
e.preventDefault();
let encodedUrl = btoa(target.href);
let url = '/tiaozhuan?target=' + encodedUrl;
window.open(url, '_blank');
}
});
对于浏览体验来说,多了一步跳转,总归是不好,但为了愉快的玩耍博客,稳妥一点更佳。现在把各个页面的评论都去掉了,只留下了唠叨跟博文评论,并且把博文的评论默认设为隐藏。倒也不是因为所谓的安全,主要是觉得评论的样式有待提高。
如果觉得跳转中间页很烦人,浏览器可以装个 Skip Redirect插件,告别所有网站的中间页跳转,直接抵达目标地址。