前言

当我们使用部分浏览器分享自己的博客时,有可能会生成带/index.html后缀的URL。

博主于上月在某公共平台分享了一篇博客,随后Waline的管理后台收到了数条评论通知,但是自己的博客页面却一条评论也没有显示,并且文章浏览量也不见增长。博主仔细排查才得知,使用IOS版Chrome浏览器分享出去的文章URL自带后缀/index.html,举例如下:

1
2
3
4
5
\\Hexo当前主题配置下生成的博客文章URL
https://owo.wyc.rest/redirect/

\\通过部分浏览器分享功能生成的博客文章URL
https://owo.wyc.rest/redirect/index.html

当我们仔细研究这两个页面后不难发现,这两个页面对于大多数插件(例如busuanzi、Waline)来说并不共享数据库,这并不是我们希望看到的。


修改永久链接配置

我们可以基于自己博客当前的情况确定修改方案,对于博主来说,博客绝大部分的评论和数据都是保存在以/结尾的URL中,所以博主会想办法保证所有用户访问博客时都使用的是以/结尾的URL,从而消除数据库不互通带来的负面影响。

并且对于很多Page服务来说,都有强制忽略URL中.html后缀的机制,例如据博主了解,Cloudflare Pages会强行忽略URL中的.html后缀,举例如下:

1
2
3
4
5
6
7
\\原URL
https://owo.wyc.rest/redirect/index.html
https://owo.wyc.rest/redirect.html

\\被CF Pages强制302重定向后的URL
https://owo.wyc.rest/redirect/
https://owo.wyc.rest/redirect

同样的,重定向后的网站与原网站不互通数据库,可以理解为是两个站点。CF Pages官方将这种机制称为Route Matching(路由匹配),并且这种机制作为用户无法手动关闭。

Route matching

If an HTML file is found with a matching path to the current route requested, Pages will serve it. Pages will also redirect HTML pages to their extension-less counterparts: for instance, will be redirected to , and will be redirected to./contact.html /contact /about/index.html /about/

首先我们需要解决生成链接的问题,幸运的是Hexo官方有相关配置提供:

我们仅需要修改Hexo的配置文件_config.yml的相关参数,即可实现生成的分享URL不再携带index.html.html后缀的效果。

1
2
3
4
5
6
7
# URL
url: https://owo.wyc.rest/
permalink: :title/
permalink_defaults:
pretty_urls:
trailing_index: false # Set to false to remove trailing 'index.html' from permalinks
trailing_html: false # Set to false to remove trailing '.html' from permalinks

JavaScript脚本实现重定向

对于此前已经在互联网上发布的链接,仅通过上述方法无法解决问题,这时需要配置301重定向,让访客在点击携带index.html后缀的URL时可以自动跳转。

自建服务器实现301重定向有两种主流的解决方案:

  1. 编辑服务器nginx配置文件批量设置重定向规则。
  2. 使用JavaScript脚本实现页面跳转和重定向。

这里博主选择的是简单便捷、易于维护的第二种方案,具体实现步骤如下:

  1. 在“source”目录下创建名为“js”的新文件夹。

  2. 在“js”文件夹下创建JavaScript文件,例如redirect.js

  3. 打开并编辑redirect.js文件,添加如下代码并保存:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 获取当前网页的 URL
    var currentUrl = window.location.href;

    // 检查是否包含 "/index.html"
    if (currentUrl.includes("/index.html")) {

    // 定义重定向的目标 URL 格式
    var redirectTo = currentUrl.replace(/\/index\.html$/, '/');

    // 进行重定向
    window.location.replace(redirectTo);
    }

    代码中的redirectTo表达式使用了正则表达式,将当前URL中的/index.html替换为/,从而实现了重定向。

    • /:正则的定界符,用于标识正则表达式的开始和结束。在JavaScript中,正则表达式通常被写在两个斜杠之间,例如/pattern/。
    • \/index\.html$:这部分是匹配 /index.html 的模式。
    • \/:匹配斜杠,需要使用反斜杠转义。
    • index\.html:匹配字符串 “index.html”。
    • $:表示匹配字符串的结尾。

    所以,/\/index\.html$/ 表示匹配以 “/index.html” 结尾的字符串。

  4. 修改主题配置文件_config.butterfly.yml中的inject相关配置,插入如下代码:

    1
    2
    bottom:  
    - <script src="/js/redirect.js"></script>

    注意:如果你的网站根目录不是‘/’,引用本地JavaScript文件时,需加上你的根目录。
    假设你的网站是https://owo.wyc.rest/blog,则设置为:

    1
    2
    bottom:  
    - <script src="/blog/js/redirect.js"></script>
  5. 保存后执行本地预览查看效果。

至此,问题被完美解决。


补充说明

在JavaScript中,window.location.replacewindow.location.href都是用于进行页面重定向的属性和方法,但它们有一些区别。

  1. window.location.replace
    • 使用replace方法时,当前页面的历史记录中不会保留被替换的URL。换句话说,用户无法通过点击浏览器的“后退”按钮返回到被替换的页面,因为被替换的页面不会出现在历史记录中。
    • 适用于一些敏感或需要用户跳转而不希望用户返回的场景。
    1
    window.location.replace("https://new-url.com");
  2. window.location.href
    • 使用href属性时,会将当前页面的URL修改为指定的URL,同时在历史记录中保留替换前的URL。用户可以通过点击浏览器的“后退”按钮返回到替换前的页面。
    • 适用于用户可能需要在之后返回到先前页面的场景。
    1
    window.location.href = "https://new-url.com";

选择使用哪个取决于你的具体需求。

  • 如果你希望用户无法返回到被替换的页面,可以使用replace方法。
  • 如果你希望用户可以返回到先前的页面,可以使用href属性。