之前做了一个小接口,运行了几年一直好好的,最近有用户反映bug,说是回调网址乱跳。
其实这是第二次接到反馈了,第一次时候以为是偶然bug,因为我用身边的安卓苹果手机测试均没问题,可是对方说就是有问题,并且还录屏了,得知手机为苹果手机。因为反应这个问题的人很少,我简单测试下认为是用户手机环境问题,未做深入调查。这回第二次接到反馈也是说苹果手机,于是引起了我的重视,猜测是不同的iOS版本导致,用户使用的应该都是最新的iOS,我的苹果测试机器是早期的iPhone6S,系统是iOS13的,由于担心电池耗电增加以及CPU性能被降级一直没升级。
为了在最新版iOS测试只能升级系统了,花了一小时左右终于升级到最新版iOS 15.4.1,立马开始测试,果然用户反映的bug重现了。我仔细检查了下,问题应该出在document.referrer,代码里用它来获取上一页的url,在安卓各个品牌各个版本系统下都是可以正常获取来源网页完整的url,而这个最新版的iOS只能获取来源网页的域名,丢失了后面的路径及文档和参数。猜测是苹果最新版(15.0以上)安全机制提升,导致只能获取到主域名。 在跳转时iOS魔改了referrer的值为仅发送host名。
我用后端代码尝试了下,结果也无法获得,更加确定了这问题只是在苹果新版系统iOS 15以上发生,至于iOS 14是否也有这个问题没有环境来测试。iOS最新版本15.4.1下只能获取来路页面url,无法获得路径和参数,那么该怎么办呢?只能让用户把网址作为参数提交到我的接口了,那么接下来需要做一个获取iOS版本的js函数给出提示:
//得到iOS系统版本 function getiOSVersion(){ var str= navigator.userAgent.toLowerCase(); var ver=str.match(/cpu iphone os (.*?) like mac os/); var striOSVersion=""; if(ver){ striOSVersion=ver[1].replace(/_/g,"."); } return striOSVersion; }
但是这样还不够,最好是判断下超过15提示用户自己整理好网址作为参数传递过来。
//检查iOS版本是否超过15 function checkEnvironment(){ var isEnvironmentOk=true; var striOSVersion=getiOSVersion(); if (striOSVersion!=""){ var intMajor=striOSVersion.split(".")[0]; if (parseInt(intMajor)>=15){ isEnvironmentOk=false; document.body.innerHTML="提示:iOS " + striOSVersion + "版本过高,不支持自动获取来路页面,请使用参数redirect_uri明确指定回调URL"; } } return isEnvironmentOk; }
这样就方便了。不会让用户一头雾水了。
另外附上document.referrer的使用说明:
document.referrer
Document.referrer
返回的是一个 URI, 当前页面就是从这个 URI 所代表的页面 跳转或打开的。referrer 属性返回载入当前文档的来源文档的URL。语法
var referrer = document.referrer;
值
如果用户直接打开了这个页面(不是通过页面跳转,而是通过地址栏或者书签等打开的),则该属性为空字符串。由于该属性只是返回一个字符串,所以不能够通过该属性引用页面的 DOM。
在
<iframe>
中,Document.referrer
会初始化为父窗口Window.location
的href
。