document.referrer在ios15.4.1无法运行正常

800 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

之前做了一个小接口,运行了几年一直好好的,最近有用户反映bug,说是回调网址乱跳。

其实这是第二次接到反馈了,第一次时候以为是偶然bug,因为我用身边的安卓苹果手机测试均没问题,可是对方说就是有问题,并且还录屏了,得知手机为苹果手机。因为反应这个问题的人很少,我简单测试下认为是用户手机环境问题,未做深入调查。这回第二次接到反馈也是说苹果手机,于是引起了我的重视,猜测是不同的iOS版本导致,用户使用的应该都是最新的iOS,我的苹果测试机器是早期的iPhone6S,系统是iOS13的,由于担心电池耗电增加以及CPU性能被降级一直没升级。

为了在最新版iOS测试只能升级系统了,花了一小时左右终于升级到最新版iOS 15.4.1(苹果公司于2022年4月发布),立马开始测试,果然用户反映的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.locationhref