关于Pjax与PWA冲突,导致地址栏异常的解决方法。
描述
那么在浏览网站时,地址栏则可能会出现意外的后缀。
后缀的内容与 PWA 中 Service Worker 的功能实现有关。
使用 workbox-build 的只有 index.html
。
使用 sw-precache 的类似于 index.html?_sw-precache=d65205fbf6be65ea9e136772f668efdb
。
分析
PWA
index.html
后缀中的 index.html
路径是根据其静态文件生成的。
通常这种情况,是想在链接中使用目录来访问指定页面。
例如 https://example.com/about/
,而不是 https://example.com/about/index.html
。
但程序并不知道,所以在生成的 precache 清单里,都是带有 index.html
的路径。
_sw-precache
后缀中的 _sw-precache
参数是根据静态文件的内容,生成的 Hash 值。
作用是用来判断文件内容是否发生变化,以便及时更新缓存。
但 sw-precache 从缓存响应请求时,并没有去掉自己的参数。
而 workbox-build 虽然也加了参数,叫 __WB_REVISION__
。
不过从缓存响应请求时,会去掉自己的参数。
Pjax
如果没用 Pjax 的话,这个后缀是不会出现在地址栏的。
但 Pjax 在改变地址栏时,逻辑优先是响应地址。
所以地址栏就会出现这些后缀。
解决方法
使用 workbox-build 的 manifestTransforms
选项。
对生成的清单进行变换,去掉路径中的 index.html
,从根源上解决问题。
声明 removeIndex
方法,并在上述选项中引用。
以我用的 v2 版 hexo-offline 插件配置文件为例。
1 | module.exports = { |
增加一段 Javascript 代码,用来劫持 Pjax 处理响应的方法。
把 request
对象中的响应地址修改为请求地址。
这里用到了 Object.defineProperty
方法,因为 request.responseURL
是只读变量,无法直接修改。
1 | // 重定向浏览器地址 |
在Butterfly的具体操作
将上述代码保存到
source\js\modify.js
。编辑
_config.butterfly.yml
,增加以下代码到inject.bottom
配置项。1
<script defer type="text/javascript" src="/js/modify.js"></script>
修改完成后,配置类似如下。
1
2
3
4
5
6
7
8# Inject
# Insert the code to head (before '</head>' tag) and the bottom (before '</body>' tag)
# 插入代码到头部 </head> 之前 和 底部 </body> 之前
inject:
head:
# - <link rel="stylesheet" href="/xxx.css">
bottom:
- <script defer type="text/javascript" src="/js/modify.js"></script>