给Hexo网站添加跳转安全提醒界面

在前一段时间,偶然间发现一篇文章,文章大意就是关于给Hexo博客给文章外部超链接增加中间跳转询问页面,当时看到之后惊为天人之作,毕竟这种界面对于提升博客自身的浏览粘度还是非常重要的,因此把文章就转载过来,做了一个标记,可是个人能力有限,实在不清楚是哪里做修改,所以搁置了。今天又看到一篇文章,同样是介绍博客外部链接增加中间跳转询问页面的,而且作者做成了插件,我测试了一下,非常棒,转载给大家。先来看白天模式的跳转界面

再来看夜间模式的跳转界面

原作者的碎碎念我们不再记录,重点是插件的使用,下面一步一步的跟随老博客站长,来安装这款非常棒的Hexo文章跳转安全提醒插件hexo-safego吧!

插件安装:

在使用该插件之前,需要先安装 cheeriocheerio 是一个轻量级的库,用于在服务器端快速、灵活地实现 jQuery 核心功能。在 hexo-safego 插件中,cheerio 被用来解析和操作生成的静态 HTML 内容,类似于在浏览器中使用 jQuery 处理 DOM 元素。这使得插件能够在生成静态页面时,处理和替换外部链接,增强博客的安全性,而不需要在客户端引入 jQuery。Hexo 一般都有这个插件,可以在 node_modules 查看,如果没有,请先执行:

1
npm install cheerio --save

一般情况下,这款插件一般都已经安装好,只需要查看一下是否存在就可以,然后是安装hexo-safego插件

1
npm install hexo-safego --save

到这里,插件的安装就完成了,下面来看插件配置。

配置插件:

在hexo根目录的_config.yml文件中添加以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# hexo-safego安全跳转插件
# see https://blog.liushen.fun/posts/1dfd1f41/
hexo_safego:
enable: true # 是否启用 hexo-safego 插件
enable_base64_encode: true # 是否启用 Base64 编码链接
enable_target_blank: true # 是否在跳转链接中添加 target="_blank"
url_param_name: 'u' # URL 参数名,用于生成跳转链接
html_file_name: 'go.html' # 跳转页面文件名
ignore_attrs: # 需要忽略的链接属性列表
- 'data-fancybox'
apply_containers: # 容器 ID 列表,如果为空则匹配整个 body
- '#article-container'
domain_whitelist: # 域名白名单列表,包含白名单中的域名的链接将被忽略
- 'qyliu.top'
apply_pages: # 生效页面路径列表,只有在这些页面上才会对链接进行处理
- '/posts/'
avatar: /info/avatar.ico # 头像图片链接
title: "清羽飞扬" # 标题
subtitle: "安全中心" # 副标题
darkmode: false # 是否启用夜间模式
debug: false # 是否启用调试模式,开启后会输出详细的调试信息

配置项说明:

原作者说添加好配置之后,使用Hexo博客的三件套就可以正常运行测试了,但我感觉还是需要适当的提前配置一下,你可以配置相关配置项对你的博客进行适配,下面是每个配置项的说明

  1. enable : Boolean, 默认值: false, 描述: 是否启用 hexo-safego 插件。

  2. enable_base64_encode : Boolean, 默认值: true, 描述: 是否对跳转链接进行 Base64 编码,如上面展示图像所示,如果关闭,则不对参数进行处理,直接放置目标路径。

  3. enable_target_blank : Boolean, 默认值: true, 描述: 是否在跳转链接中添加 target=”_blank” 属性,在新页面跳转。

  4. url_param_name : String, 默认值: “u”, 描述: 跳转页面的 URL 参数名称,可自行定义。

  5. html_file_name : String, 默认值: “go.html”, 描述: 生成的跳转页面文件名。

  6. ignore_attrs : Array, 默认值: [‘data-fancybox’], 描述: 需要忽略的链接属性列表,这里默认忽略灯箱,如果你有其他需要忽略的可以继续添加。

  7. apply_containers : Array, 默认值: [‘#article-container’], 描述: 指定要处理的容器列表,这里默认为butterfly文章部分。

  8. domain_whitelist : Array, 默认值: [], 描述: 域名白名单列表,使用字符串匹配,如果跳转链接中包含该字符串,则忽略。

  9. apply_pages : Array, 默认值: [‘/posts/‘], 描述: 生效页面路径列表。

  10. avatar : String, 默认值: “https://fastly.jsdelivr.net/gh/willow-god/hexo-safego@latest/lib/avatar.png“, 描述: 跳转页面的头像图片链接,可以使用相对地址。

  11. title : String, 默认值: “网站名称”, 描述: 跳转页面的标题。

  12. subtitle : String, 默认值: “网站副标题”, 描述: 跳转页面的副标题。

  13. darkmode : Boolean, 默认值: false, 描述: 是否启用夜间模式。

  14. debug : Boolean, 默认值: false, 描述: 是否启用调试模式,开启后会输出详细的调试信息。

我自己的配置:

关于文件配置,我只是关注了五个地方

  1. 白名单列表,把里面的域名设置成自己的域名

    1
    2
    domain_whitelist:  # 域名白名单列表,包含白名单中的域名的链接将被忽略
    - 'qyliu.top'
  2. 生效页面路径

    1
    2
    apply_pages:  # 生效页面路径列表,只有在这些页面上才会对链接进行处理
    - '/posts/'

    我自己的网站是articles,在原作者这里是posts,我自己做了调整。

  3. 头像问题

    1
    avatar: /info/avatar.ico  # 头像图片链接

    这里是头像链接设置,需要调整好,不然不会显示头像

  4. 网站标题的设置

    1
    title: "清羽飞扬"  # 标题

    需要修改为自己的网站提示关键词,毕竟和原作者不是一个称呼。

  5. 是否开启夜间模式

    1
    darkmode: false  # 是否启用夜间模式

    现在很多主流的Hexo博客主题都支持夜间模式,开启之后会更加方便,当然需要自己魔改的魔改一下。

进阶操作

如果你有前端基础,除了以上配置 ,你还可以自行定义相关页面,打开插件中的go.html,这里我为了方便大家修改,没有进行代码压缩,其中CSS分为三部分:通用配置,夜间专用,白天专用:

  1. 通用配置:这里包含除了夜间和白天配色,其余所有css配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    body {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    font-family: Arial, sans-serif;
    overflow: hidden;
    flex-direction: column;
    }
    .avatar-placeholder, .avatar {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    margin-bottom: 15px;
    display: block;
    }
    .avatar {
    display: none;
    }
    .description {
    font-size: 18px;
    }
    .subtitle {
    font-size: 12px;
    margin-bottom: 20px;
    color: #C4C4C4;
    }
    .loading {
    text-align: center;
    padding: 30px;
    border-radius: 18px;
    animation: fadein 2s;
    width: 400px;
    max-width: 90%;
    }
    @keyframes fadein {
    from { opacity: 0; }
    to { opacity: 1; }
    }
    .content {
    margin-bottom: 20px;
    }
    .url-text {
    margin-bottom: 10px;
    font-size: 16px;
    letter-spacing: 1px;
    }
    .jump-url {
    font-size: 20px;
    display: block;
    margin-top: 5px;
    margin-bottom: 25px;
    padding: 15px;
    border-radius: 8px;
    height: 25px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    }
    .countdown-text {
    margin-top: 12px;
    font-size: 12px;
    }
    .button-container {
    display: flex;
    justify-content: center;
    gap: 20%;
    margin-top: 20px;
    }
    .button {
    padding: 10px 20px;
    border-radius: 16px;
    border: none;
    cursor: pointer;
    font-size: 16px;
    width: 120px;
    height: 40px;
    }
    .cancel-button {
    color: black;
    }
    .confirm-button {
    color: white;
    }
    .progress-bar {
    width: 100%;
    border-radius: 5px;
    overflow: hidden;
    height: 10px;
    margin-top: 20px;
    }
    .progress {
    width: 100%;
    height: 100%;
    transition: width 1s;
    }
  2. 夜间配置:夜间配置主要配置夜间的一些配色:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    {% if darkmode %}
    body {
    background: linear-gradient(135deg, #364f6b, #222831);
    }
    .loading {
    background: #393e46;
    color: #EFEFEF;
    box-shadow: 0 4px 8px rgba(100, 100, 100, 0.1);
    }
    .description {
    color: #F3F3F3;
    }
    .url-text, .countdown-text {
    color: #EFEFEF;
    }
    .jump-url {
    border: 1px solid #777;
    background-color: #333;
    color: #EFEFEF;
    }
    .cancel-button {
    background-color: #872C2C;
    color: #FFF;
    }
    .confirm-button {
    background-color: #28566F;
    color: #FFF;
    }
    .progress-bar {
    background-color: #444;
    }
    .progress {
    background-color: #888;
    }
    {% endif %}
  3. 白天配置:同上,包含白天配色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    {% if not darkmode %}
    body {
    background: linear-gradient(135deg, #fce38a, #eaffd0);
    }
    .loading {
    background: rgba(255, 255, 255, 0.7);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }
    .url-text {
    color: #333;
    }
    .jump-url {
    border: 1px solid #ccc;
    background-color: #F7F9FE;
    color: #333;
    }
    .countdown-text {
    color: #515151;
    }
    .cancel-button {
    background-color: #a6e3e9;
    }
    .confirm-button {
    background-color: #3fc1c9;
    }
    .progress {
    background-color: #abedd8;
    }
    {% endif %}
  4. 注意代码之中的{% if not darkmode %}不能删除,这个是模板文件的配置,表示当在符合要求时将其包裹的内容放置到文件中,否则抛弃,我将夜间和白天的配色分开目的是尽量压缩生成的html页面代码量,加快加载速度。下面的JS选项,如果无必要,请不要删除。除此之外,你还可以更改其中的结构,但是请尽量不要修改类名,有些类名可能绑定有特定的跳转。

魔改杂记

在开发过程中,我曾使用时间来判断白天或者夜间,添加对应的类来调整暗色和亮色,但是我发现在加载后切换亮暗的一瞬间总会有一部分闪烁,很影响观感,于是我去掉了按照时间自动切换的功能,改为选择亮暗,尽可能给不想改源码的童鞋更多的,更个性化的选择。

在白名单链接方面,我使用字符串匹配,这样可能不如通配符的匹配性那么强,但是优点在于好理解。在原作者中还有一些配置项,比如额外参数:externalnofollownoopenernoreferrer,经过烤炉后,我选择直接将这个添加到网站中,因为这个选项非常常用,下面是解释:

  1. external:指示链接指向外部网站。这通常是为了便于样式和 JavaScript 控制,但对搜索引擎爬虫没有直接影响。
  2. nofollow:告诉搜索引擎不要跟踪这个链接,也就是说,不要将链接目标的权重传递给目标页面。因此,使用 nofollow 可以防止搜索引擎通过这个链接爬取目标页面并将其权重传递。
  3. noopener:用于防止新打开的页面能够通过 window.opener 属性获得对原页面的引用。这主要是为了防止某些安全风险,例如页面篡改和钓鱼攻击。
  4. noreferrer:告诉浏览器在导航到链接目标时不发送 HTTP Referer 头信息。这对于保护隐私和安全有一定帮助。

这些功能都是非常常用的,可以进一步保护我们的网站,并且也不会有什么副作用,并且经过go.html包裹了的地址也显然没有了被爬取的必要,所以我将这个配置项直接添加到了代码中,减少参数量。

写在最后,分享一下作者的信息吧

博客链接:https://blog.liushen.fun

文章链接:https://blog.liushen.fun/posts/1dfd1f41/

开源地址:https://github.com/willow-god/hexo-safego