前言
最近在排查Safari在隐私模式下页面参数丢失的问题,如果通过Safari直接打开B页面,此时在B页面可以正常获取到页面链接上的参数,但是如果Safari先打开A页面,然后通过A页面再跳转到B页面(A、B页面部署在不同域名下),此时的B页面通过JS就获取不到链接上的参数了🤔,这样就会导致一些依赖页面参数的功能出现异常!
问题演示
B页面链接格式如下:xx.qq.com?au=xx...
通过一下代码获取页面链接及页面参数:
如果是隐私模式下单独打开B页面
此时可以看到是能够正常获取到页面完整链接(包括参数)的。符合预期
但是如果先打开A页面,再从A页面跳到B页面(A、B域名不同),我们再来看看结果:
从上图可以看到,此时location.search
就已经获取不到了,location.href
拿到的值也不再包括location.search
了。
那么Safari在隐私模式下的这种做法是为了做什么呢?
Safari隐私浏览
通过查询资料后得知,在 Safari 17 中,隐私浏览功能更加私密,并新增了防御措施,以抵御一些最先进的追踪技术。技术改进包括:
- 链接跟踪保护
- 阻止已知跟踪器的网络负载,包括 CNAME 隐藏的已知跟踪器
- 高级指纹保护
- 具有网站或历史记录访问权限的扩展程序默认处于关闭状态
链接跟踪保护
Safari 的“隐私浏览”功能在用户浏览不同网站时,针对目标 URL 中的跟踪信息实施了两项新的保护措施。具体涵盖的 URL 部分包括查询参数和 URL 片段。这些保护措施旨在使目标网站上运行的第三方脚本更难以通过读取 URL 来关联跨网站的用户活动。
在文档上有这样一段话:
翻译过来就是:在跨站导航后的目标网站上,所有尝试读取完整 URL或参数 的第三方脚本(例如使用 location.search、location.href 或 document.URL)都将获得一个不含查询参数或片段的 URL 版本。
也就是说Safari隐私模式下链接参数丢失必须满足以下两种情况:
- 页面发生了跨域名跳转
- 获取链接或参数在第三方脚本中执行(其实就是JS与html模版不在同一个域名下)
解决方案
同域跳转
既然不同发生跨域跳转,那么同域名跳转是不是就能正常获取页面链接参数了
同域部署
如果第一种方案满足不了业务场景,那么可以尝试将html
模版文件与JS
文件用相同域名部署,也能规避Safari隐私模式的限制
内联脚本
如果你的业务既要跨域跳转又不想改部署方案,那么内联脚本这种方案比较适合你,我们可以在html
模版文件内插入一段JS脚本去获取页面链接及参数,这样的话这段JS就不属于第三方脚本了。
比如:
然后再使用的地方直接读取window上的selfLink
、selfSearch
可以看到通过读取内联脚本挂在window上的selfLink
、selfSearch
可以正常获取,而直接读取window.location.href
会丢失search
参数。